{"id":15114992,"url":"https://github.com/psalm/psalm-plugin-laravel","last_synced_at":"2026-05-10T23:02:23.538Z","repository":{"id":37079149,"uuid":"171369793","full_name":"psalm/psalm-plugin-laravel","owner":"psalm","description":"A Psalm plugin for Laravel","archived":false,"fork":false,"pushed_at":"2026-04-02T17:30:29.000Z","size":2245,"stargazers_count":327,"open_issues_count":29,"forks_count":75,"subscribers_count":9,"default_branch":"master","last_synced_at":"2026-04-03T04:20:26.912Z","etag":null,"topics":["laravel","looking-for-maintainer","php","php-static-analysis","psalm","psalm-plugin","static-analysis"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/psalm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing/README.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["alies-dev"]}},"created_at":"2019-02-18T23:11:27.000Z","updated_at":"2026-04-02T17:30:33.000Z","dependencies_parsed_at":"2023-02-17T03:46:00.698Z","dependency_job_id":"d08f4843-5ce9-406c-9cc5-79dfb2d5020c","html_url":"https://github.com/psalm/psalm-plugin-laravel","commit_stats":{"total_commits":628,"total_committers":38,"mean_commits":"16.526315789473685","dds":0.6098726114649682,"last_synced_commit":"a91791e30e918bcc7dcc59a1307b1f63e705c78a"},"previous_names":[],"tags_count":99,"template":false,"template_full_name":null,"purl":"pkg:github/psalm/psalm-plugin-laravel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psalm%2Fpsalm-plugin-laravel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psalm%2Fpsalm-plugin-laravel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psalm%2Fpsalm-plugin-laravel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psalm%2Fpsalm-plugin-laravel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/psalm","download_url":"https://codeload.github.com/psalm/psalm-plugin-laravel/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/psalm%2Fpsalm-plugin-laravel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31446531,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T15:22:31.103Z","status":"ssl_error","status_checked_at":"2026-04-05T15:22:00.205Z","response_time":75,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["laravel","looking-for-maintainer","php","php-static-analysis","psalm","psalm-plugin","static-analysis"],"created_at":"2024-09-26T01:43:38.226Z","updated_at":"2026-05-10T23:02:23.532Z","avatar_url":"https://github.com/psalm.png","language":"PHP","funding_links":["https://github.com/sponsors/alies-dev"],"categories":["Development"],"sub_categories":["Quality Check"],"readme":"# Psalm plugin for Laravel\n\nLaravel static analysis with built-in security scanning.\n\n[![Packagist version](https://img.shields.io/packagist/v/psalm/plugin-laravel.svg)](https://packagist.org/packages/psalm/plugin-laravel)\n[![Packagist downloads](https://img.shields.io/packagist/dt/psalm/plugin-laravel.svg)](https://packagist.org/packages/psalm/plugin-laravel)\n[![Type coverage](https://shepherd.dev/github/psalm/psalm-plugin-laravel/coverage.svg)](https://shepherd.dev/github/psalm/psalm-plugin-laravel)\n[![Tests](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/tests.yml/badge.svg)](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/tests.yml)\n[![Tests](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/test-laravel-app.yml/badge.svg)](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/test-laravel-app.yml)\n\nThe only free tool that combines deep Laravel type analysis with taint-based vulnerability detection.\nCatches SQL injection, XSS, SSRF, shell injection, file traversal, and open redirects, without running your code.\n\n\u003e [!NOTE]\n\u003e Already using Larastan? psalm-laravel **complements** it with security analysis that PHPStan cannot provide.\n\n\n![Screenshot](/docs/assets/screenshot.png)\n\n\n## Security scanning\n\nPlugin ships Laravel-specific taint stubs that track user input from source to sink across your entire codebase.\nUnlike pattern-matching tools, Psalm follows dataflow across function boundaries, catching vulnerabilities that simpler scanners miss.\n\n```php\n// psalm-laravel catches this:\nRoute::get('/search', function (Request $request) {\n    $sortByColumn = $request-\u003einput('sort'); // Tainted source: user input from HTTP request\n    User::where('name', $request-\u003einput('name'))\n        -\u003eorderBy($sortByColumn) // 🚨 Tainted sink: unvalidated user input used in query builder\n        -\u003eget();\n\n// Psalm output:\n// ERROR TaintedSql: Detected tainted SQL\n});\n```\n\nTaint analysis also works across helper functions, service classes, and any number of call layers.\n\n```php\n// UserController.php\n$user-\u003esiteSettinsg['articles_sort'] = $request-\u003einput('sort'); // Tainted source: user input from HTTP request\n$user-\u003esave();\n\n// ArticlesConstoller.php\nArticles::query()\n    -\u003eorderBy($user-\u003esiteSettinsg['articles_sort']) // 🚨 Tainted sink: unvalidated user input used in query builder\n    -\u003eget();\n\n// Psalm output:\n// ERROR TaintedSql: Detected tainted SQL\n```\n\nYou can read more about how the plugin's taint analysis works and what vulnerabilities it detects in [docs/security.md](docs/security.md).\n\n## Quickstart\n\n### Step 1: Install\n\nSince [Psalm 7.x](https://github.com/vimeo/psalm/releases) is currently in beta, allow dev (or beta) packages first:\n\n```bash\ncomposer config minimum-stability dev \u0026\u0026 composer config prefer-stable true\ncomposer require --dev psalm/plugin-laravel:^4.8\n```\n\n### Step 2: Generate a Laravel-tailored `psalm.xml`\n\n```bash\n./vendor/bin/psalm-laravel init\n```\n\nThis writes a `psalm.xml` at the project root with the plugin already enabled, sensible `errorLevel`, and Laravel-friendly issue handler defaults. Pass `--level 1` (strictest) through `--level 8` (most lenient) to pick a starting strictness. Pass `--force` to overwrite an existing `psalm.xml` without prompting.\n\n### Step 3: Run\n\n```bash\n./vendor/bin/psalm-laravel analyze\n```\n\n`analyze` delegates to `vendor/bin/psalm` and passes the exit code through, so you can also invoke `./vendor/bin/psalm` directly. Security taint analysis runs automatically, no extra flags needed.\n\n**Existing projects:** the first run will likely report many issues. Create a [baseline](https://psalm.dev/docs/running_psalm/dealing_with_code_issues/#using-a-baseline-file) to suppress them and focus only on new code:\n\n```bash\n./vendor/bin/psalm --set-baseline=psalm-baseline.xml\n```\n\nFrom here, gradually increase `errorLevel` (start at `4`, work toward `1`) and shrink the baseline over time.\n\n### Optional: wire up CI in one command\n\n```bash\n./vendor/bin/psalm-laravel add github\n```\n\nWrites a ready-to-commit `.github/workflows/psalm.yml` that runs the plugin on every push and pull request. See [docs/github-actions.md](docs/github-actions.md) for what the generated workflow does and how to customize it.\n\n## Configuration\n\nYou can customize Psalm configuration using [XML config](https://psalm.dev/docs/running_psalm/configuration/)\nand/or [cli parameters](https://psalm.dev/docs/running_psalm/command_line_usage/).\n\nSee [docs/config.md](docs/config.md) for all configuration options.\n\n## Custom checks\n\nThe plugin ships advanced Laravel-aware static analysis checks that extend Psalm's built-in diagnostics.\nSee [docs/issues/index.md](docs/issues/index.md) for the full catalog.\n\n## Versions \u0026 Dependencies\n\nMaintained versions:\n\n| Laravel Psalm Plugin                      | PHP  | Laravel    | Psalm  | Status |\n|-------------------------------------------|------|------------|--------|--------|\n| 4.x                                       | ^8.2 | 12, 13     | 7-beta | Stable |\n| 3.x ([upgrade v4 to](docs/upgrade-v4.md)) | ^8.2 | 11, 12, 13 | 6      | Stable |\n| 2.12+                                     | ^8.0 | 9, 10, 11  | 5, 6   | Legacy |\n\n_(Older versions of Laravel, PHP, and Psalm were supported by version 1.x of the plugin, but they are no longer maintained)_\n\nSee [releases](https://github.com/psalm/psalm-plugin-laravel/releases) for more details about supported PHP, Laravel and Psalm versions.\n\n## How it works\n\nUnder the hood it reads Laravel's native `@method` annotations on facade classes and generates alias stubs based on `Illuminate\\Foundation\\AliasLoader` (including aliases from your `config/app.php` and package discovery). It also ships hand-crafted stubs for taint analysis and special cases.\n\nIt also parses SQL schema dumps (`php artisan schema:dump`) and PHP migration files to infer column names and types in your database models.\n\n\n## Psalm-Laravel or Larastan?\n\n**Use both.** They solve different problems:\n\n- **Larastan** excels at Laravel-specific type rules: `model-property` validation, `view-string` checks, and 17+ custom rules.\n- **Psalm-Laravel** in addition to type checks, it provides taint-based security analysis that PHPStan structurally [cannot offer](https://github.com/phpstan/phpstan/issues/8038), plus deep type support for auth guards, Eloquent attributes, scopes, attributes, etc.\n\nPsalm and PHPStan use almost the same annotation syntax, so they work side by side without conflicts.\n\n**Larastan checks your types. We check your security. Use both.**\n\n\n## Contributing\n\nMaintained by [@alies-dev](https://github.com/sponsors/alies-dev).\nThere are [contributing docs](docs/contributing/README.md) that may help you (and your agents) with contributions.\n\nAreas where help is especially needed:\n- **Taint analysis coverage**: adding a stub is 5 to 15 lines of annotations and protects thousands of apps. See the [authoring guide](docs/contributing/taint-analysis.md).\n- **Type inference** for Laravel magic (Eloquent, Facades, Collections).\n- **New checks** that enforce Laravel best practices.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsalm%2Fpsalm-plugin-laravel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpsalm%2Fpsalm-plugin-laravel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpsalm%2Fpsalm-plugin-laravel/lists"}