PHPackages                             psalm/plugin-laravel - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. psalm/plugin-laravel

ActivePsalm-plugin[Utility &amp; Helpers](/categories/utility)

psalm/plugin-laravel
====================

Psalm plugin for Laravel

v4.3.2(1mo ago)3274.9M—1%75[25 issues](https://github.com/psalm/psalm-plugin-laravel/issues)[5 PRs](https://github.com/psalm/psalm-plugin-laravel/pulls)20MITPHPPHP ^8.2CI passing

Since Feb 18Pushed 1mo ago9 watchersCompare

[ Source](https://github.com/psalm/psalm-plugin-laravel)[ Packagist](https://packagist.org/packages/psalm/plugin-laravel)[ Docs](https://github.com/psalm/psalm-plugin-laravel)[ GitHub Sponsors](https://github.com/alies-dev)[ RSS](/packages/psalm-plugin-laravel/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (43)Versions (137)Used By (20)

[![Packagist version](https://camo.githubusercontent.com/cdd0aa342205390ac15be04e46b28580ca0c1de54d94cbf3de263c141cc5064a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7073616c6d2f706c7567696e2d6c61726176656c2e737667)](https://packagist.org/packages/psalm/plugin-laravel)[![Packagist downloads](https://camo.githubusercontent.com/b914002156b062f954231019fda1b2f42544bbd572ca9826d5790ac5fdef1b88/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7073616c6d2f706c7567696e2d6c61726176656c2e737667)](https://packagist.org/packages/psalm/plugin-laravel)[![Type coverage](https://camo.githubusercontent.com/fb93d70a6dc74873a2936fa8bda61ddf40daaeccbc41eaf47fdced84998bc9f8/68747470733a2f2f73686570686572642e6465762f6769746875622f7073616c6d2f7073616c6d2d706c7567696e2d6c61726176656c2f636f7665726167652e737667)](https://shepherd.dev/github/psalm/psalm-plugin-laravel)[![Tests](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/test.yml/badge.svg)](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/test.yml)[![Tests](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/test-laravel.yml/badge.svg)](https://github.com/psalm/psalm-plugin-laravel/actions/workflows/test-laravel.yml)

Psalm plugin for Laravel
========================

[](#psalm-plugin-for-laravel)

Laravel static analysis with built-in security scanning.

The only free tool that combines deep Laravel type analysis with taint-based vulnerability detection. Catches SQL injection, XSS, SSRF, shell injection, file traversal, and open redirects — without running your code.

> Already using Larastan? psalm-plugin-laravel **complements** it with security analysis that PHPStan cannot provide.

[![Screenshot](/docs/assets/screenshot.png)](/docs/assets/screenshot.png)

Security scanning
-----------------

[](#security-scanning)

Plugin ships Laravel-specific taint stubs that track user input from source to sink across your entire codebase. Unlike pattern-matching tools, Psalm follows dataflow across function boundaries — catching vulnerabilities that simpler scanners miss.

```
// psalm-plugin-laravel catches this:
Route::get('/search', function (Request $request) {
    $query = $request->input('q');
    DB::statement("SELECT * FROM users WHERE name = '$query'");
    // TaintedSql: user input flows directly to the SQL query
});
```

Taint analysis also works across helper functions, service classes, and any number of call layers:

```
// Cross-function taint flow — pattern-matching tools miss this:
function getUserQuery(Request $request): string {
    return "SELECT * FROM users WHERE name = '" . $request->input('name') . "'";
}

Route::get('/users', function (Request $request) {
    DB::statement(getUserQuery($request));
    // Psalm catches this: taint flows Request -> getUserQuery() -> DB::statement()
});
```

### What it detects

[](#what-it-detects)

VulnerabilityOWASPExamplesSQL InjectionA03:2021`DB::statement()`, `DB::unprepared()`, raw query methodsShell InjectionA03:2021`Process::run()`, `Process::command()`XSSA03:2021`Response::make()` with unescaped contentSSRFA10:2021`Http::get()`, `Http::post()` with user-controlled URLsFile TraversalA01:2021`Storage::get()`, `File::delete()` with user-controlled pathsOpen RedirectA01:2021`redirect()`, `Redirect::to()` with user-controlled URLsCrypto misuseA02:2021Tracks encryption/hashing taint escape and unescapeSecurity scanning runs automatically alongside type analysis — no extra configuration needed.

### How it compares

[](#how-it-compares)

ToolLaravel-aware typesTaint analysisFree**psalm-plugin-laravel**YesYes (dataflow)YesLarastanYesNo (PHPStan can't)YesEnlightn ProPartialNo (rule-based)$99+/projectSonarQubeGeneric PHPYes (generic)Paid editions onlySemgrepPro tier onlyPattern-basedLimited free tierSnyk CodeGenericYes (generic)FreemiumVersions &amp; Dependencies
---------------------------

[](#versions--dependencies)

Maintained versions:

Laravel Psalm PluginPHPLaravelPsalmStatus4.x^8.212, 137Stable3.x^8.211, 126Stable2.12+^8.09, 10, 115, 6Legacy*(Older versions of Laravel, PHP, and Psalm were supported by version 1.x of the plugin, but they are no longer maintained)*

See [releases](https://github.com/psalm/psalm-plugin-laravel/releases) for more details about supported PHP, Laravel and Psalm versions. Upgrading from v3? See the [v3 → v4 upgrade guide](docs/upgrade-v4.md).

Quickstart
----------

[](#quickstart)

### Step 1: Install

[](#step-1-install)

```
composer require --dev psalm/plugin-laravel
```

### Step 2: Configure

[](#step-2-configure)

If you didn't use Psalm on the project before, you need to create a Psalm config:

```
./vendor/bin/psalm --init
```

### Step 3: Enable the plugin:

[](#step-3-enable-the-plugin)

```
./vendor/bin/psalm-plugin enable psalm/plugin-laravel
```

### Step 4: Run

[](#step-4-run)

Run your usual Psalm command:

```
./vendor/bin/psalm
```

Security taint analysis runs automatically as part of the standard analysis in Psalm 7. No extra flags are needed.

### Step 5 (existing projects): Create a baseline

[](#step-5-existing-projects-create-a-baseline)

On an existing codebase, the first run will likely report many issues. A [baseline file](https://psalm.dev/docs/running_psalm/dealing_with_code_issues/#using-a-baseline-file) lets you suppress all current issues and focus only on new code:

```
./vendor/bin/psalm --set-baseline=psalm-baseline.xml
```

From here, gradually increase `errorLevel` (start at `4`, work toward `1`) and shrink the baseline over time.

Configuration
-------------

[](#configuration)

You can customize Psalm configuration using [XML config](https://psalm.dev/docs/running_psalm/configuration/)and/or [cli parameters](https://psalm.dev/docs/running_psalm/command_line_usage/).

See [docs/config.md](docs/config.md) for all configuration options.

Custom issues
-------------

[](#custom-issues)

The plugin emits custom issues beyond Psalm's built-in checks:

- [NoEnvOutsideConfig](docs/issues/NoEnvOutsideConfig.md) — `env()` called outside `config/` directory
- [InvalidConsoleArgumentName](docs/issues/InvalidConsoleArgumentName.md) — `argument()` references undefined command argument
- [InvalidConsoleOptionName](docs/issues/InvalidConsoleOptionName.md) — `option()` references undefined command option
- [MissingView](docs/issues/MissingView.md) — `view()` references a non-existent Blade template (opt-in)
- [MissingTranslation](docs/issues/MissingTranslation.md) — `__()` or `trans()` references an undefined translation key (opt-in)
- [ModelMakeDiscouraged](docs/issues/ModelMakeDiscouraged.md) — `Model::make()` used instead of `new Model()`

How it works
------------

[](#how-it-works)

Under 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.

It also parses SQL schema dumps (`php artisan schema:dump`) and PHP migration files to infer column names and types in your database models.

psalm-plugin-laravel or Larastan?
---------------------------------

[](#psalm-plugin-laravel-or-larastan)

**Use both.** They solve different problems:

- **Larastan** excels at Laravel-specific type rules: `model-property` validation, `view-string` checks, and 17+ custom rules.
- **psalm-plugin-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.

Psalm and PHPStan use almost the same annotation syntax, so they work side by side without conflicts.

**Larastan checks your types. We check your security. Use both.**

Contributing
------------

[](#contributing)

Maintained by [@alies-dev](https://github.com/sponsors/alies-dev). PRs and issues welcome — first-time contributors too. There are [contributing docs](docs/contributing/README.md) that may help you (and your agents) with contributions.

Areas where help is especially needed:

- **Taint analysis coverage** — adding a stub is 5–15 lines of annotations and protects thousands of apps. See the [authoring guide](docs/contributing/taint-analysis.md).
- **Type inference** for Laravel magic (Eloquent, Facades, Collections)
- **New checks** that enforce Laravel best practices

###  Health Score

76

—

ExcellentBetter than 100% of packages

Maintenance88

Actively maintained with recent releases

Popularity64

Solid adoption and visibility

Community51

Growing community involvement

Maturity91

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 60.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~28 days

Recently: every ~0 days

Total

93

Last Release

54d ago

Major Versions

1.x-dev → v2.11.12025-01-26

v2.11.1 → v3.0.0-rc12025-02-16

v2.12.1 → v3.0.0-rc22025-02-16

2.x-dev → v3.0.52026-02-24

3.x-dev → v4.0.0-beta.12026-03-16

PHP version history (10 changes)1.2.0PHP ^7.1.3|^8

v1.3.0PHP ^7.2|^8

v1.4.1PHP ^7.3|^8

v1.5.2PHP ^7.3|^8.0

v2.0.0PHP ^8.0

v2.2.0PHP ^8.0.2

v2.10.0PHP ^8.1

v1.4.10PHP ^7.3 || ^8.0

v3.0.0-rc1PHP ^8.2

v4.0.0-beta.1PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/37a992956f2ceb043547091360fe71dacdd2b227d5450e7022b2a53660ba4e44?d=identicon)[muglug](/maintainers/muglug)

![](https://www.gravatar.com/avatar/819d5d9fe8f78d00cc5dd7972cbb9e4f049c9bff7186e0e401f3191b3f137885?d=identicon)[weirdan](/maintainers/weirdan)

---

Top Contributors

[![alies-dev](https://avatars.githubusercontent.com/u/5278175?v=4)](https://github.com/alies-dev "alies-dev (1015 commits)")[![mr-feek](https://avatars.githubusercontent.com/u/5747667?v=4)](https://github.com/mr-feek "mr-feek (246 commits)")[![lptn](https://avatars.githubusercontent.com/u/150333538?v=4)](https://github.com/lptn "lptn (101 commits)")[![muglug](https://avatars.githubusercontent.com/u/2292638?v=4)](https://github.com/muglug "muglug (85 commits)")[![Nielsvanpach](https://avatars.githubusercontent.com/u/10651054?v=4)](https://github.com/Nielsvanpach "Nielsvanpach (84 commits)")[![caugner](https://avatars.githubusercontent.com/u/495429?v=4)](https://github.com/caugner "caugner (41 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (17 commits)")[![actions-user](https://avatars.githubusercontent.com/u/65916846?v=4)](https://github.com/actions-user "actions-user (10 commits)")[![mzur](https://avatars.githubusercontent.com/u/2457311?v=4)](https://github.com/mzur "mzur (10 commits)")[![ronb-lendesk](https://avatars.githubusercontent.com/u/55106709?v=4)](https://github.com/ronb-lendesk "ronb-lendesk (9 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (9 commits)")[![danog](https://avatars.githubusercontent.com/u/7339644?v=4)](https://github.com/danog "danog (6 commits)")[![tm1000](https://avatars.githubusercontent.com/u/564256?v=4)](https://github.com/tm1000 "tm1000 (5 commits)")[![MDG11](https://avatars.githubusercontent.com/u/59790837?v=4)](https://github.com/MDG11 "MDG11 (4 commits)")[![asbiin](https://avatars.githubusercontent.com/u/25419741?v=4)](https://github.com/asbiin "asbiin (4 commits)")[![pthiers](https://avatars.githubusercontent.com/u/1180952?v=4)](https://github.com/pthiers "pthiers (3 commits)")[![tjmmm](https://avatars.githubusercontent.com/u/2571506?v=4)](https://github.com/tjmmm "tjmmm (3 commits)")[![crynobone](https://avatars.githubusercontent.com/u/172966?v=4)](https://github.com/crynobone "crynobone (3 commits)")[![eithed](https://avatars.githubusercontent.com/u/795678?v=4)](https://github.com/eithed "eithed (2 commits)")[![hendrikheil](https://avatars.githubusercontent.com/u/19904485?v=4)](https://github.com/hendrikheil "hendrikheil (2 commits)")

---

Tags

laravellooking-for-maintainerphpphp-static-analysispsalmpsalm-pluginstatic-analysislaraveldevpsalmpsalm-plugin

###  Code Quality

TestsPHPUnit

Static AnalysisRector

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/psalm-plugin-laravel/health.svg)

```
[![Health](https://phpackages.com/badges/psalm-plugin-laravel/health.svg)](https://phpackages.com/packages/psalm-plugin-laravel)
```

###  Alternatives

[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k25.9M107](/packages/laravel-cashier)[laravel/passport

Laravel Passport provides OAuth2 server support to Laravel.

3.4k85.0M532](/packages/laravel-passport)[flarum/core

Delightfully simple forum software.

211.3M1.9k](/packages/flarum-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
