ngmy/laravel-ide-helper-eloquent
Generate PHPDoc annotations for Eloquent models to improve IDE autocompletion and static analysis. This Laravel package inspects your models, database schema, and relationships to produce accurate @property, @method, and relationship hints, making model code easier to navigate in PhpStorm, VS Code,...
Add the package as a dev-only dependency so it never ships to production:
composer require --dev ngmy/laravel-ide-helper-eloquent
Publish the config if you need to change discovery paths or output location (tag/provider name depends on the version — run php artisan vendor:publish and pick the ide-helper-eloquent entry), then generate the helper file:
php artisan ide-helper:eloquent
The first thing to look at is the generated _ide_helper_eloquent.php at the project root (path is configurable). Open one of your models in PhpStorm/VS Code and confirm that $model->some_attribute and $model->someRelation now resolve with types. Add the helper file to .gitignore — it is build output, not source. The canonical first use case is: fresh clone → composer install → php artisan migrate → php artisan ide-helper:eloquent → full autocomplete and static-analysis coverage on every Eloquent model.
Because this is a 0.x package, treat the public API (config keys, command name, output file name) as unstable between minor releases; pin it in composer.json and re-read the changelog before bumping to 0.5.
Regenerate as part of the boot pipeline. The file goes stale the moment you add a migration or a relation. Hook generation into composer.json so it runs after autoload rebuilds:
"scripts": {
"post-autoload-dump": [
"@php artisan ide-helper:eloquent"
]
}
Guard this so it does not fail when no database is available (see Gotchas) — wrap in a shell script that skips on failure, or only run it locally.
Layer it with barryvdh/laravel-ide-helper. They solve different halves of the problem: this package types your models (attributes, casts, relations, accessors/mutators), while the other generates facade/container/_ide_helper.php stubs. Install both and keep their outputs as separate gitignored files; they do not collide.
Pair with Larastan/PHPStan. The generated @property, @property-read, @method and relation annotations are what let PHPStan reason about $user->posts->first()->title instead of mixed. Run ide-helper:eloquent before phpstan analyse in your CI job — the static-analysis step is where this package pays for itself.
Scope the scan in config. Restrict model_paths to app/Models (or wherever your models live) and explicitly exclude legacy/generated model directories and vendor. Scanning the whole app/ tree is slow and produces noise. If you have modules, list each module's model directory.
Map non-standard column types. Database drivers report types inconsistently (SQLite affinity, MySQL json, enum, spatial types). Override them in the custom_db_types mapping so relations/attributes are typed as array, string, etc. rather than mixed.
Keep relations as methods and properties. Day-to-day, $post->author (property access) and $post->author() (query builder) are different call sites; verify both are annotated after generation so neither path falls back to mixed.
enum/boolean/json become loose affinities). Generate against the same driver you analyze against, or lean on custom_db_types.php artisan config:clear (or optimize:clear); a stale cached config silently ignores new model_paths/exclude entries and you will chase phantom missing models.resolveRelationUsing, or conditional traits won't be detected. Add a hand-maintained @method/@property-read above the class — but if you edit the generated file, it is overwritten on the next run, so put manual annotations on the model itself._ide_helper_eloquent.php as regenerable. Review the diff locally after a schema change; a large unexpected diff usually means a wrong DB connection or a changed custom_db_types map, not a generator bug.sed, which will fight you at the next release.php artisan ide-helper:eloquent right after upgrading and diff the output plus your config file against the published stub. Minor 0.x bumps in this project have historically been where config keys and command signatures shift; if the command errors out immediately, vendor:publish --force the config and compare keys before assuming a bug.How can I help you explore Laravel packages today?