Open-source project
larastan/larastan avatar
larastan/larastan

Larastan boots your app so the analyser can see the types only runtime knows

⚗️ Adds code analysis to Laravel improving developer productivity and code quality.

6,542 stars530 forksPHPMIT

At a glance

What is it?
Six and a half thousand stars for the PHPStan extension that gives Laravel's dynamic returns real types, and that pays for them by loading your application container on every analysis run.
Who is it for?
Larastan is the tool that made type coverage on Laravel a normal expectation rather than an enthusiast project, and the reason is a design decision the README states plainly instead of hiding: it boots your application container because the types you want are the ones that only exist at runtime.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • larastan/larastan6,542 ★ · +5
Star history
Repository2026-10-122026-10-23
larastan/larastan6.5k6.5k

5 Stars in the last 11 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Why it calls itself code analysis instead of static analysis

The single most useful sentence in the README is a disclaimer. It says that by definition static analysis does not load any of your application code, and that Larastan boots your application's container so it can resolve types that are only possible to compute at runtime. That is why the project uses the term code analysis instead of static analysis.

Everything else in the design follows from that. Laravel's most-used methods return `mixed` to a naive analyser because the concrete type depends on a container binding, an Eloquent relation path, or the class name of a view. Larastan's answer is to construct the real application and ask it. The cost side is equally explicit in practice: analysis needs a bootable application, it is slower and heavier than pure PHPStan, and the README tells you what to do when you hit the ceiling, which is `./vendor/bin/phpstan analyse --memory-limit=2G`.

The positioning is worth reading against the topic list. The tags are `code-analysis`, `laravel`, `php` and `phpstan`, and the description says it adds code analysis to Laravel improving developer productivity and code quality. The README frames the payoff as catching whole classes of bugs before you write tests, and lists supporting most of Laravel's magic as the headline feature. The project was created by Can Vural and Nuno Maduro and is maintained by those two plus Viktor Szépe, which is a useful signal: this is not a community bolt-on, it sits next to the PHPStan and Laravel maintainers.

Installation takes a Composer require and a neon file

The README calls it three steps and it is honestly three steps. Requirements are PHP 8.2 or newer and Laravel 11.15 or newer.

bash
composer require --dev "larastan/larastan:^3.0"

Then you create `phpstan.neon` or `phpstan.neon.dist` in the application root:

code
includes:
    - vendor/larastan/larastan/extension.neon
    - vendor/nesbot/carbon/extension.neon

parameters:

    paths:
        - app/

    # Level 10 is the highest level
    level: 5

And then you analyse:

bash
./vendor/bin/phpstan analyse

One note from the same section worth keeping: if you are analysing a Laravel package rather than an application you may need `orchestra/testbench` installed. The reason follows directly from the boot-the-container design. Larastan needs a real application instance to resolve bindings, and Testbench is the standard way to build one outside a full app.

The repository tree confirms the shape of the project. `extension.neon` is the file your config includes, `bootstrap.php` is where the container gets booted, `stubs/` holds type stubs for Laravel internals, and `phpstan.neon.dist` plus `phpstan-baseline.neon` show that the project analyses itself at a level strict enough to require a baseline. `e2e/`, `tests/`, `phpunit.xml.dist` and `RELEASE.md` are the ordinary machinery of a package that ships rules for other people's frameworks.

Level five is a starting point, not a ceiling

The example config comments that level 10 is the highest, and then sets level 5. That is the honest recommendation: a Laravel codebase that has never seen a type checker will not survive level 9 on day one, and starting there just produces a wall of errors nobody reads.

Two escape valves are documented, and they are for different situations. The first is inline suppression, which PHPStan supports and Larastan inherits:

php
// @phpstan-ignore-next-line
$test->badMethod();

$test->badMethod(); // @phpstan-ignore-line

The second is configuration level suppression by regex:

yaml
parameters:
    ignoreErrors:
        - '#Call to an undefined method .*badMethod\(\)#'

And for older codebases there is the baseline, which is the mechanism that makes adoption realistic on an application with hundreds of existing violations:

bash
./vendor/bin/phpstan analyse --generate-baseline

The README describes the baseline's purpose precisely, which is not to hide problems but to stop new ones. It writes out every current error so new code can be held to a higher standard than the code around it. That is the migration pattern for almost any large PHP codebase and it is the single most useful sentence in the setup section if you are trying to introduce this to a team.

The configuration surface also points out where the Laravel specific work lives: `docs/rules.md` for configurable rules, `docs/features.md` for the feature list, `docs/custom-types.md` for custom PHPDoc types, `docs/custom-config-parameters.md` for extra config keys, and `docs/errors-to-ignore.md` for the parts of Laravel that are still too magical to model. That last file is the most honest signal in the repository. The project admits a residue of Laravel behaviour it cannot infer, and gives you the list.

Version mapping has a gap and releases show the trade

The README publishes a supported versions table, and it contains a defect worth mentioning because anyone choosing a version needs it. The table reads: Laravel below 9 maps to Larastan 1.x; greater than 9.0 and at least 11.16 maps to 2.x; and 11.16 or later maps to 3.0 or later. The 11.16 boundary appears twice, so the middle row cannot be distinguished from the last one as written, and the README requirement line below it says Laravel 11.15 or newer while the table says 11.16. Treat 11.16 as the real floor and confirm against Packagist before pinning.

The release history is more informative than the table. v3.12.0 landed on 2026-09-10 and extended `view-string` coverage. v3.12.1 on 2026-09-13 raised the requirement to PHPStan 2.2.14 or newer, which is worth planning around since it means a Larastan upgrade can force a PHPStan upgrade in the same commit. v3.12.2 on 2026-09-19 is the most instructive, because its fixes describe the exact edges of the boot-the-container approach.

It improved unused view detection for mail content, `Mail::send()`, concatenated view names and slash-separated Blade view names. It preserves unsigned column types when an integer cast is applied, and supports those in higher-order collection `sum()` calls. It recognises quiet increment and decrement methods forwarded by models. It treats schema dump columns without `NOT NULL` as nullable. It uses `Builder<Model>` when a relationship path cannot be followed through an unknown model, and it detects Octane container injection inside arrow functions. Every one of those is a case where the type only becomes knowable by looking at real framework internals rather than at a signature, and the Octane one is a nice detail: Octane injects things into arrow functions in a way that even Larastan initially missed.

Reading the maintenance signals honestly

The numbers here are strong. 6,514 stars and 506 forks for a package that most teams install rather than fork is a healthy ratio, and 94 open issues on a project this size is manageable rather than alarming. The last push was 2026-09-21 and the repository is not archived, MIT licensed, with the default branch on `3.x`.

The release cadence is the best evidence of health. Three releases in September 2026, with the newest two landing within a week of each other, means the maintainers are shipping fixes continuously rather than batching them. The fact that AGENTS.md and CLAUDE.md sit in the root tells you contributors are expected to arrive through tooling, and RELEASE.md and UPGRADE.md suggest version transitions are handled deliberately.

The thing to weigh is architectural rather than operational. A project whose value comes from booting your application inherits your application's fragility. If your app needs a database connection to resolve a type, if a service provider throws at boot, or if configuration differs between local and CI, Larastan inherits those problems and reports them as analysis failures. That is not a flaw in the project, it is the price of the design, and it is the reason the `--memory-limit` option and the baseline workflow exist in the README at all. The comparison people search for, Larastan versus plain PHPStan, comes down to whether you want resolved framework types badly enough to pay for a boot on every run.

Editorial conclusion

Larastan is the tool that made type coverage on Laravel a normal expectation rather than an enthusiast project, and the reason is a design decision the README states plainly instead of hiding: it boots your application container because the types you want are the ones that only exist at runtime. That trade buys you resolved Eloquent relations, fluent builder generics and accurate return types on everything Laravel resolves dynamically, and it costs you analysis speed, memory pressure and the need for a recent PHPStan. The release history shows what maintaining that bargain actually involves, since 3.12.1 raised the floor to PHPStan 2.2.14 and 3.12.2 fixed Octane container injection detection in arrow functions. Set the level to what your codebase can survive, generate a baseline if it cannot, and treat the unresolved parts as a worklist rather than a verdict.

Frequently asked questions

What is PHPStan used for?

PHPStan analyses PHP code without running it and reports type errors before your tests execute. Larastan is a PHPStan extension that adds knowledge of Laravel on top, booting the application container so it can resolve types that only exist at runtime, and it is installed with `composer require --dev "larastan/larastan:^3.0"`.

Is Larastan static analysis?

The README says no, and explains why. Static analysis by definition does not load your application code, and Larastan boots your application's container so it can resolve types that are only possible to compute at runtime. That is the reason for the term code analysis instead of static analysis.

Which Laravel version does my Larastan version support?

The README table lists 1.x for Laravel below 9, 2.x above 9.0 and at least 11.16, and 3.0 or later for 11.16 and above. That 11.16 boundary appears in two rows, and the requirements line says Laravel 11.15+, so treat 11.16 as the floor and confirm the exact constraint on Packagist before pinning.

How do I introduce Larastan to a large existing codebase?

Generate a baseline with `./vendor/bin/phpstan analyse --generate-baseline`. The README describes this as a way to write a configuration file containing all current errors so that new code can follow a higher standard than the old code. Start at a level the codebase can survive rather than jumping to the maximum of 10.

Can I analyse a Laravel package instead of an application?

Yes, but you may need `orchestra/testbench` installed. Because Larastan boots the application container to resolve types, it needs a real application instance to work against, and Testbench is the standard way to build one outside a full application.

Official sources

  1. Issues
  2. larastan/larastan on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/larastan-larastan.svg)](https://hysenlabs.com/projects/larastan-larastan)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/larastan-larastan.svg)](https://hysenlabs.com/projects/larastan-larastan)

Was this useful?