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

Phpstorm Attributes Laravel Package

jetbrains/phpstorm-attributes

JetBrains PhpStorm attributes provide PHP 8 attributes for richer code completion and analysis in PhpStorm, including Deprecated, ArrayShape, ObjectShape, and Immutable. Bundled with PhpStorm; add as a dev dependency for other static analysis tools.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. jetbrains/phpstorm-attributes is not an architectural component — it is a metadata vocabulary. The package is a small set of #[\Attribute] classes (Deprecated, ArrayShape, ObjectShape, Immutable, Pure, ExpectedValues, NoReturn, Language, FileReference) under the JetBrains\PhpStorm namespace. PHP attributes are inert unless reflected upon, so these classes introduce no runtime coupling, no service provider, no config, no middleware, no lifecycle hooks. They can be applied at any layer of a Laravel application (controllers, JsonResource::toArray(), config providers, DTOs, service boundaries) without touching dependency wiring. Critically, it is a dev-only dependency, so production autoloading and container boot are unchanged. The correct mental model is "structured comments the IDE and analysers can read."

Integration feasibility. Extremely high. One composer require --dev jetbrains/phpstorm-attributes line, no publish step, no environment variables, no bootstrap. The attributes ship bundled with PhpStorm 2020.3+, so the composer install only exists to satisfy CI tools and non-PhpStorm analysers that would otherwise raise "class not found." There is no migration, no schema change, and no data surface. Reversibility is essentially total: composer remove plus leaving the attribute lines in place (harmless) or stripping them.

Technical risk.

  • Annotation drift (highest risk). Attributes are assertions, not contracts. Nothing validates an #[ArrayShape] against the actual array a method returns. A stale shape annotation is worse than no annotation because both the IDE and reviewers trust it. Mitigation: pair with phpstan-phpstorm + PHPStan in CI, or explicitly accept IDE-only, best-effort semantics.
  • IDE concentration risk. The value is delivered almost entirely inside PhpStorm. On VS Code or a mixed-IDE team, this package is near-zero-return noise. Quantify PhpStorm coverage before committing.
  • Ecosystem signal. 415 stars and 0 dependents is thin for a normal library, but the usual abandonment risk is partially neutralised here because the attribute definitions ship inside the IDE — the composer package is a fallback for tooling, not the delivery mechanism. Apache-2.0 is permissive and carries no legal review burden.
  • Advisory-not-enforced semantics. #[Immutable] does not prevent mutation; #[Pure] does not prevent side effects; #[NoReturn] does not guarantee termination. Teams that mistake these for enforcement may deprioritise readonly properties or real encapsulation.
  • Runtime reflection edge case. Under composer install --no-dev, any first-party code calling ReflectionClass::getAttributes() on these namespaces would hit class-not-found. Laravel core does not do this; custom code might.
  • Version floor. Requires PHP 8.0+ (the ≤7.4 single-line form is a legacy curiosity irrelevant to modern Laravel). 1.2 added PHP 8.4 compatibility, confirming an actively maintained floor.

Key questions a TPM must answer before green-lighting.

  1. What percentage of the engineering org is on PhpStorm 2020.3+? If below roughly 70%, scope this as an opt-in convention rather than a standard.
  2. Will we fund the CI half — phpstan-phpstorm plus a PHPStan level that actually parses attributes — or are we buying IDE sugar only? This decision determines whether drift is caught or merely discovered.
  3. Who owns the annotation convention, and which surfaces are in scope (public APIs, DTOs, resources, config defaults) versus explicitly out of scope (private helpers, trivial scalars)?
  4. Does #[Deprecated] plug into an existing deprecation policy with named owners and semver alignment, or are we inventing one retroactively?
  5. Do we accept that these are advisory annotations with no runtime guarantee, and does the team understand the difference?

Integration Approach

Stack fit. The package is a natural fit for a Laravel application on PHP 8.1+ with Composer, because Laravel's idioms are exactly the shapes these attributes describe: untyped structured arrays from config(), JsonResource::toArray() payloads, data_get() consumers, form-request rule arrays, and json_decode(..., false) / DB::select() rows that arrive as mixed. #[ArrayShape] gives Laravel the closest thing it has to typed config() without a DTO rewrite; #[ObjectShape] covers dynamic object rows. There is no Laravel service provider to register and no config/phpstorm-attributes.php to publish — which is the point.

Compatibility.

  • Coexists cleanly with PHPStan, Psalm, PHP-CS-Fixer, and Laravel Pint. Unknown attributes are ignored by tools that don't understand them, so partial adoption is safe — annotated and unannotated code can live side by side indefinitely.
  • Pin loosely as ^1.3. The release cadence is slow, which is appropriate for a metadata-only package; slow cadence here is a feature, not a warning sign.
  • The --no-dev/--dev split is the one compatibility line to state explicitly in the convention doc: production installs lack the classes, so no runtime code may reflect over them.
  • The 1.2 release fixed PHP 8.4 compatibility; verify the pinned version against the target PHP version during the spike rather than assuming.

Migration path. There is no data or runtime migration — only a convention migration. Sequence it as follows:

  1. Spike (days, one engineer). Add the dev dependency on a branch, confirm PhpStorm lights up #[Deprecated] and #[ArrayShape] in a scratch file, and confirm CI is byte-for-byte unaffected.
  2. Pilot on two high-traffic surfaces. One JsonResource::toArray() annotated with #[ArrayShape], and one method on the internal deprecation backlog annotated with #[Deprecated(reason:…, replacement:…) where replacement uses %class% / %method% / %parameter0% substitution so the quick-fix rewrites call sites.
  3. Decide on the CI half. If yes: add phpstan-phpstorm and enable attribute parsing for the pilot paths only, keeping the existing baseline intact so the change is a delta, not a cliff.
  4. Write the one-page convention. When to annotate (public boundaries, deprecation notices, resource payloads, config defaults) and when not to (private helpers, single-value returns, anything that would need a comment to justify itself).
  5. Opportunistic retrofit. Rule: annotate what you already touch. No big-bang sweep — a sweep generates review churn and stale annotations faster than it generates value.
  6. Wire deprecations into the release process. Every CHANGELOG deprecation entry ships in the same PR as its #[Deprecated] attribute. This is where the package pays for itself: it converts a changelog line into an inline codemod during Laravel major-version upgrades and internal package revamps.

Sequencing against adjacent work. Land this before or alongside a Laravel major upgrade, not after — the quick-fix value is realised during the migration window while the deprecated call sites are still live. Remove attributes only when the underlying symbols are deleted.

Operational Impact

Maintenance. Near zero. No runtime process, no scheduled job, no infrastructure, no database, no configuration to drift. Ongoing cost is a pinned version plus automated dependency bumps (Dependabot/Renovate). The abandonment scenario is largely pre-absorbed by JetBrains shipping the attribute definitions inside the IDE itself; worst case, a CI-only stub file restores class resolution.

Support. The support surface is developer education, not operations — the tickets read "is this annotation correct?" rather than "why is production down." Owner should be a tech lead or DevEx function, not platform/SRE. Budget for one annotated example PR and one short walkthrough; there is no certification, no vendor contract, and no escalation path beyond the PhpStorm issue tracker.

Scaling. Annotation cost scales with the number of public boundaries, not with traffic. Request latency, memory, and production autoload are unaffected — zero runtime footprint means zero production scaling concern. In a monorepo or multi-team codebase, the scaling risk is inconsistency: three teams annotating three different ways, or one team annotating exhaustively while another ignores it. Mitigate with the convention doc plus CI enforcement; without CI, scale amplifies drift.

Failure modes to monitor.

  1. Silent drift — a refactor changes an array's keys, the #[ArrayShape] doesn't move, and the IDE now lies. Caught only by static analysis in CI; if CI is out of scope, treat this as an accepted, documented risk.
  2. IDE fragmentation — non-PhpStorm engineers see no benefit and experience the convention as overhead. Mitigate by scoping adoption to the surfaces that also help PHPStan/Psalm, so everyone gets some value.
  3. Runtime reflection — custom code instantiating these attributes in production fails under --no-dev. Add a lint rule or a note in the convention.
  4. Over-annotation — exhaustive annotation of internals produces noisy diffs and review friction, leading to quiet abandonment. Keep scope to public contracts and data flows.
  5. Version skew — using an attribute name that exists only in an unreleased or newer tag breaks CI class resolution. Pin ^1.3 and verify new attribute names against the tag before use.
  6. False confidence — treating #[Immutable] as enforcement and skipping readonly or real encapsulation. State plainly in the convention: these are advisory.

Ramp-up. Fifteen to thirty minutes per engineer for the two attributes that matter (#[Deprecated], #[ArrayShape]); #[ObjectShape], ExpectedValues with backed enums, and #[NoReturn] are learned on demand. A single brown-bag session and one merged exemplar PR is sufficient onboarding. Net effect on new hires is positive: key-level autocomplete on resource payloads and config arrays shortens the "what does this endpoint actually return?" phase that normally consumes their first weeks.

Adoption metrics worth reporting upward. Count of annotated public boundaries; percentage of shipped deprecations carrying a replacement hint (codemod coverage); PHPStan baseline size as an inverse quality signal; review comments referencing payload shape or deprecation, trending toward zero. Framed for executives: a one-line, zero-runtime, Apache-2.0 dev dependency that reduces avoidable defects and turns framework upgrades into guided quick-fixes — a low-cost enabler to fold into existing feature work rather than a standalone roadmap item.

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.
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite
faghy/laracashbook
roundly-consulting/google-places-for-laravel
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
adachsoft/changelog-linter