symfony/annotations-pack
Symfony annotations-pack is a Composer metapackage that pulls in the libraries needed to use annotations in Symfony applications, chiefly doctrine/annotations. It simplified dependency setup during the Symfony 3.4 to 4.x transition.
Architecture fit
symfony/annotations-pack is a Composer metapackage ("type": "symfony-pack"), not a library. It ships no PHP code, no service provider, no config, no Laravel package-discovery entry. Its entire payload is a require block that pulls in Doctrine's annotation reader plus a cache implementation, so that Symfony Flex can "auto-install a capability" when a recipe declares it.
That model has no analogue in Laravel. Laravel's equivalent is either (a) requiring the concrete library directly, or (b) a first-party package with extra.laravel.providers. A symfony-pack type is inert outside Flex — Composer will install it without error and it will do nothing. In a Laravel codebase this package is therefore not an architecture fit at any layer: it is a Symfony distribution convention leaking into a non-Symfony app.
The underlying capability (Doctrine annotation reading with a cache layer) can be relevant to Laravel — most commonly via doctrine/orm entity mapping, gedmo/doctrine-extensions, or legacy bundles migrated from Symfony. That is a real requirement; the pack is not the right vehicle for it.
Integration feasibility
Trivially installable (it is a no-op install) and therefore a false positive for feasibility: "composer require worked" will be mistaken for "we now have annotations." Actual integration work is unchanged and lives entirely in the consumer:
AnnotationReader and a cached reader (PsrCachedReader / CachedReader) in a service provider.Cache repository is PSR-16; doctrine/annotations 2.x expects PSR-6, so a bridge is typically required.storage/framework/cache/annotations) with correct permissions in containerized/read-only-filesystem deploys.Technical risk
* requirements. That means composer update can silently move doctrine/annotations 1.x → 2.x and doctrine/cache 1.x → 2.x. The 2.0 line of doctrine/cache removed the Cache interface and doctrine/annotations 2.0 dropped doctrine/cache in favor of PSR-6 — a dependency-graph-breaking change delivered by a routine update.doctrine/cache transitively through a metapackage you don't control is a classic way to deadlock resolution against laravel-doctrine/*, gedmo/*, or an existing symfony/cache. The pack gives you no version lever; you must add explicit replace/conflict/direct requires anyway, at which point the pack is pure overhead.Key questions
require doctrine/annotations:^1.14 || ^2.0 directly with an explicit constraint?composer.lock already constrain doctrine/cache or psr/cache, and will a wildcard requirement conflict?Stack fit
Poor as a package, neutral-to-workable as a capability. The correct Laravel shape is: explicit doctrine/annotations constraint + an application-owned cached reader bound in a service provider + a cache store you already operate (symfony/cache Psr6Cache over Laravel's store, or the framework cache for the 1.x CachedReader path). Nothing about that requires a pack.
Migration path
symfony/annotations-pack. Replace it in the plan with direct, pinned requirements. If a dependency transitively requires the pack (rare — packs are usually root-only), that is a smell worth escalating.composer remove symfony/annotations-pack after adding the direct requires. Because it contributes only requirements, removal is safe once the real libraries are declared — but verify composer why doctrine/annotations still resolves after removal.@ORM\, @Gedmo\, @Annotations\) and convert to attributes class-by-class. Attributes need no reader, no cache, no autoload dance — the migration deletes the operational surface rather than adding it.Compatibility
doctrine/annotations 2.x + PSR-6 is the coherent target; 1.x is maintenance-only.laravel-doctrine/orm) often pin doctrine/annotations ^1.x; check that before choosing 2.x, and let that pin drive the decision rather than the pack.Sequencing
doctrine/annotations and the PSR-6/PSR-16 bridge explicitly, with bounded constraints and a lockfile commit.storage/framework/cache, not the package default.Maintenance
The pack itself adds no maintenance and no value; it adds constraint opacity. Your team inherits an unpinned transitive dependency it did not choose and cannot tune without duplicating it. Net maintenance is strictly worse than a direct require, for zero functional gain. Expect a future cleanup ticket titled "remove annotations-pack."
Support
No vendor, no docs beyond the Symfony Flex pack convention, no issue tracker activity of consequence. Support load falls entirely on internal Doctrine knowledge. Escalation path: none external.
Scaling
Scaling is a function of the annotation reader, not the pack. Annotation parsing is CPU-bound on cold cache; at scale it must be pre-warmed at deploy rather than lazily built per container. In horizontally scaled / ephemeral-container setups this means a shared or build-time cache artifact — an operational obligation the metapackage does nothing to surface.
Failure modes
doctrine/annotations/doctrine/cache; runtime Class not found or interface-mismatch errors in an unrelated deploy.doctrine/cache pin blocks an unrelated upgrade.composer dump-autoload --classmap-authoritative or excluding dev classes causes annotation classes to be unresolvable in production only.Ramp-up
Near zero for the pack (there is nothing to learn) and non-trivial for the capability: engineers must understand the reader, cache backend semantics, autoloading constraints, and deploy-time warmup. Attributes reduce that ramp to zero — which is the strongest argument for sequencing the attribute migration first and treating annotations as a bounded legacy bridge with a removal date.
How can I help you explore Laravel packages today?