Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Ide Helper Laravel Package

barryvdh/laravel-ide-helper

Generate IDE helper files for Laravel that provide accurate autocompletion and PHPDocs directly from your project source. Supports facades, Eloquent models, fluent methods, factory builders, and PhpStorm container meta, keeping IDE hints up to date.

View on GitHub
Deep Wiki
Context7

Getting Started

Install it as a dev-only dependency — it never runs in production code paths:

composer require --dev barryvdh/laravel-ide-helper
php artisan vendor:publish --provider="Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider" --tag=config

Then run the three generators once to see what you get:

php artisan ide-helper:generate   # -> _ide_helper.php (Facades, macros, fluent)
php artisan ide-helper:models -M  # -> _ide_helper_models.php + @mixin on models
php artisan ide-helper:meta       # -> .phpstorm.meta.php (container, factories)

Where to look first: open config/ide-helper.php before touching anything else. Almost every quirk you'll hit later (include_fluent, ignored_models, additional_relation_types, write_model_magic_where, use_generics_annotations, model_hooks) is a config flag, not code you need to write. The generated files themselves are throwaway artifacts — read them only to debug why a completion is missing.

First real use case: a fresh Laravel 10/11 app where Auth::user(), Cache::get(), and Post::whereTitle(...) all show as "undefined method" in your IDE. After ide-helper:generate, PhpStorm/VSCode+Intelephense resolves every facade to the underlying class with full signatures. That single win is why the package has ~15k stars; the model PHPDocs are the second, larger win.

Commit the config, gitignore the generated output:

_ide_helper.php
_ide_helper_models.php
.phpstorm.meta.php

…unless you have a team that prefers stable, diffable completions — in which case commit them and let CI verify freshness (see below). Pick one convention and enforce it; mixed conventions are the number-one source of merge-conflict pain with this package.

Implementation Patterns

Regenerate automatically on dependency changes

The most valuable habit is wiring generation into Composer so nobody ever works against stale stubs:

"scripts": {
  "post-update-cmd": [
    "Illuminate\\Foundation\\ComposerScripts::postUpdate",
    "@php artisan ide-helper:generate",
    "@php artisan ide-helper:meta"
  ],
  "post-autoload-dump": [
    "@php artisan ide-helper:generate"
  ]
}

Keep ide-helper:models out of this hook — it needs a database and writes to source files, so it belongs in an explicit, deliberate step.

Model generation: choose one strategy per team

The three modes are not interchangeable; each trades off IDE fidelity against repository noise.

Mode Flag Output location Best for
Write inline -W / --write PHPDoc on the model class itself Solo devs, small apps, apps where you want PHPDoc to travel with the model
Separate file -N / --nowrite _ide_helper_models.php only Teams that never want generated code in git diff
Mixin -M / --write-mixin One-line @mixin IdeHelperPost on the model, full docs in the helper file Recommended default for teams — stable one-line diffs, no duplicate-class complaints

The mixin mode is the sweet spot because it writes a synthetically-named class (IdeHelperPost) into the helper file, avoiding the "duplicate class declaration" warning your IDE throws when the model and the helper both define App\Models\Post.

Generation command patterns

# specific models only
php artisan ide-helper:models "App\Models\Post" "App\Models\User"

# entire non-standard directories
php artisan ide-helper:models --dir="app/Domain/Billing/Models" --dir="app/Domain/CRM/Models"

# skip base/abstract/vendor models
php artisan ide-helper:models --ignore="App\Models\BaseModel,App\Models\Pivot"

# destructive reset — use deliberately, not routinely
php artisan ide-helper:models -RW

# minimal eloquent helper for @mixin \Eloquent QueryBuilder methods
php artisan ide-helper:models --write-eloquent-helper

For multi-tenant or modular apps, prefer per-directory runs in a script over a single global run — it keeps the diff scoped and makes git blame meaningful.

CI freshness gate

If you commit generated files, add a check so they can't drift:

- run: php artisan ide-helper:generate
- run: php artisan ide-helper:models -N -M   # sqlite in-memory, no writes to models
- run: git diff --exit-code -- _ide_helper.php _ide_helper_models.php

Note the -M/-N combination in CI: it produces the helper file without mutating model source files, so the job stays read-only against your code. Use -M (in-memory SQLite) on generate too if any facade needs a DB connection:

php artisan ide-helper:generate -M

Extend generation with model hooks

When your models have columns or virtual attributes the introspector can't see (JSON casts flattened into accessors, computed properties, enum-backed attributes), don't hand-edit the PHPDoc — it'll be overwritten. Write a hook:

class StatusHook implements ModelHookInterface
{
    public function run(ModelsCommand $command, Model $model): void
    {
        if (! $model instanceof HasStatus) {
            return;
        }

        $command->setProperty('status_label', 'string', true, false, 'Human-readable status');
        $command->unsetMethod('whereStatusLabel');
    }
}

Register it in config/ide-helper.php under model_hooks. This is the sanctioned extension point and it survives every regeneration — treat it as the answer whenever someone says "the generator is wrong about my model."

Adjacent integrations worth enabling

  • include_fluent => true — gives you chained $table->string(...)->nullable()->index() completion in migrations. Cheap, high value, zero risk.
  • Macros with type hints — Str::macro('concat', function (string $a, string $b): string {...}) produces real signatures in _ide_helper.php. Untyped closures produce nothing useful.
  • additional_relation_types / additional_relation_return_types — required if you use custom relationship classes (e.g. from staudenmeir/eloquent-has-many-deep style packages), otherwise relations silently generate as mixed.
  • ide-helper:meta — resolves app(Foo::class) and resolve() to concrete types inside the container. Regenerate after binding changes in service providers; the meta file is environment-sensitive and rarely worth committing.

Coexistence with static analysis

IDE Helper and Larastan are complementary, not redundant. Larastan resolves types for PHPStan; IDE Helper resolves them for the editor. Run both — IDE Helper's generated PHPDoc frequently resolves Larastan warnings for free, because the stub file gives PHPStan concrete signatures to analyze.

Gotchas and Tips

ide-helper:models -W is destructive by default. The README warns you: without --reset, it appends new properties/methods but never updates existing ones. A renamed column leaves a stale @property behind forever. --reset replaces everything, including hand-written @property notes and docblock commentary. Practical rule: run -RW on a clean working tree, review git diff before committing, and never run it while other branches are in flight.

Database connection is mandatory for models. The command introspects information_schema; a broken .env gives you an empty or partial generation that looks successful. In CI, force the in-memory driver with -M. Locally, if you just switched branches and the DB is behind, you'll generate PHPDoc for columns that no longer exist — run php artisan migrate first.

Facades will be silently omitted without a working connection. Same root cause on ide-helper:generate: any facade that touches the DB during boot gets skipped. -M (SQLite in-memory) fixes it. If a specific facade is still missing, check the extra / implementation map in config/ide-helper.php — you can point the generator at the concrete class manually.

Never resolve merge conflicts in _ide_helper.php by hand. It's a multi-megabyte generated file; taking "both sides" produces duplicate declarations that break indexing in confusing ways. Resolution is always: git checkout --theirs/--ours (either), then re-run ide-helper:generate. Better: gitignore it and avoid the conflict entirely.

The _ide_helper.php file is large enough to slow your IDE. In PhpStorm, right-click it → Mark as Plain Text or exclude it from indexing while keeping it in the project. Don't delete it — models need it for the @mixin \Eloquent QueryBuilder methods (newQuery(), whereX(), whereXOrFail()). If you want to avoid the full file, ide-helper:models --write-eloquent-helper emits a minimal version that satisfies just that requirement.

Real-time facades appear only after they've been used. Facade::class style real-time facades are generated on demand into storage/framework/cache; the helper only picks them up if the file already exists. So: hit the route (or run the command) that uses the facade, then run ide-helper:generate. First-time setup on a fresh clone will miss them — that's expected, not a bug.

Duplicate PHPDoc causes "cannot find class" / ambiguity warnings. This happens when you run -W and -N at different times, leaving both inline PHPDoc and an _ide_helper_models.php entry with the same class. Fix: pick a mode, delete the stale artifact, regenerate. Related: Laravel's @mixin \Eloquent on Model requires _ide_helper.php to exist, otherwise even first() has no completion.

--write-mixin requires the model file to be writable. Read-only or generated model directories (e.g. models generated from a schema package) make -M fail silently or partially. Use -N for those and rely on file-level discovery.

Macros without type hints generate nothing. No error, no warning — just an absent completion. If a colleague's macro works and yours doesn't, compare the closure signature. Union types and ?Type work; mixed and untyped params do not produce useful PHPDoc.

write_model_magic_where inflates large models. Every column yields a where<Column>() static method. On a 60-column model with a dozen relations that's hundreds of @method lines — noisy diffs and slower IDE indexing. Set write_model_magic_where => false on wide models and keep it on for the rest. The same logic applies to write_model_relation_count_properties / ..._exists_properties if you use withCount/withExists heavily.

Version compatibility is a hard boundary. 3.x targets Laravel 10+. On Laravel 8/9 you must pin ^2.0, which has a materially different flag surface — most blog posts and StackOverflow answers you'll find describe 2.x behavior (--nowrite, --reset semantics and the meta-file handling differ). Check the installed major before following a tutorial.

Config caching can hide your changes. If php artisan config:cache has run, edits to config/ide-helper.php are ignored by the generator command. php artisan config:clear before debugging "why is my include_fluent flag not taking effect."

Exclude generated files from formatters. Laravel Pint and PHP-CS-Fixer will happily reformat _ide_helper.php, producing enormous diffs on every run. Add them to pint.json's exclude or .php-cs-fixer.dist.php's finder exclusions.

Treat staleness as a bug, not an annoyance. A developer who's been on a branch for three days with no regeneration will spend real time chasing phantom type errors. If you don't commit the files, put ide-helper:generate in post-autoload-dump (as above) and mention ide-helper:models in your contributing docs as a "run after migrating" step. If you do commit them, the CI diff gate is what keeps them honest.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core