typo3/class-alias-loader
Composer plugin that adds backwards-compatible class aliases for renamed PHP classes. Packages declare alias map files in composer.json; the loader rewrites vendor/autoload.php and transparently calls class_alias() when old names are requested. No-op when no maps exist.
Architecture fit
post-autoload-dump and rewrites vendor/autoload.php to register an additional autoloader. This is a build-time concern, so it sits outside Laravel's normal integration surface (providers, facades, config) and must be reasoned about as part of the dependency/build pipeline rather than the application architecture.class_alias(). This is functionally equivalent to a one-line class_alias() in bootstrap/app.php or a files autoload entry — the differentiator is that alias maps can be shipped by the library itself via its composer.json extra block, so consumers get compatibility without writing glue code.Illuminate\Foundation\AliasLoader / config/app.php aliases. Those map short names to facade classes and are resolved by Laravel's own loader. typo3/class-alias-loader only handles fully-qualified old → new class name renames. Any pitch that claims it removes Laravel facade aliases from config/app.php is incorrect; the two systems are orthogonal and can collide if both register the same alias.ClassAliasMap::getClassNameForAlias() is useful for string-based class references — Eloquent Relation::morphMap values already persisted in model_type columns, serialized queued job class names, and config-driven class strings. Those survive a class rename only if string resolution is normalised, which the plugin offers.Integration feasibility
class-alias-maps in the root composer.json, run composer dump-autoload. No application code changes.config.allow-plugins entry for typo3/class-alias-loader, and the plugin must be installed in production dependencies (not require-dev) if aliases are used at runtime, because the generated vendor/autoload.php references the loader class.Technical risk
vendor/autoload.php violates immutable-vendor policies (read-only bind mounts, verified builds, composer install --no-scripts in CI). This is the single biggest adoption blocker.class_alias() preserves the class name, not the method signatures. A class that was renamed and had its constructor or method signatures changed will still fatal at runtime. Teams frequently misread "alias" as "compatible".composer dump-autoload --optimize --classmap-authoritative, and OPcache preloading all see only the new class names. Static analysis will report the old names as nonexistent.dump-autoload, so a deploy that changes maps without re-dumping (or without an OPcache reset/FPM reload) serves stale aliases.Key questions
bootstrap/app.php class_alias() block or a files autoload entry is simpler and avoids vendor mutation entirely.vendor/? If not, this is disqualified regardless of merit.morphMap / queue payloads referencing old class names be migrated, or only aliased?Stack fit
vendor/ scenario and into any situation where a third-party library ships its own alias map — that is the highest-leverage use case and requires zero work from us.config/app.php aliases and AppServiceProvider.Migration path
typo3/class-alias-loader to an exact version (e.g. 2.0.1) — the project's own release note explicitly advises pinning.config.allow-plugins entry in the root composer.json.app/Compatibility/ClassAliasMap.php returning old => new pairs; declare it under extra.typo3/class-alias-loader.class-alias-maps. Set always-add-alias-loader: true only if runtime map registration is genuinely needed (the README advises against it).composer dump-autoload, then run the full test suite plus a smoke test asserting class_exists('Old\Name').Compatibility
--classmap-authoritative in the sense that aliases will not appear in the authoritative map; lazy class_exists() lookups on old names still work because the loader is registered separately, but this needs verification in a staging deploy, not assumption.rector, laravel/framework upgrade guides, or symfony/deprecation-contracts — it complements them by removing the hard cutover.Sequencing
vendor/autoload.php is rewritten as expected, and CI builds still pass with a read-only vendor simulation.Build vs. buy
class_alias() block in a bootstrap provider is 10 lines, statically analysable via a stub file, and removes the Composer-plugin and vendor-mutation risk entirely. Recommend evaluating this baseline first.Maintenance
Support
vendor/autoload.php is corrupted or an alias resolves to a nonexistent class, the failure surfaces as a fatal Class not found deep in framework bootstrap with no obvious link to this package. Add an onboarding runbook: "if class-not-found after deploy, check composer dump-autoload ran and the alias map is valid PHP."extra block and re-dump).Scaling
Failure modes
| Failure | Symptom | Mitigation |
|---|---|---|
Plugin blocked by allow-plugins |
Aliases silently never registered | Assert class_exists() on an old name in a smoke test |
Read-only / immutable vendor/ |
dump-autoload fails the build |
Fail fast in CI; do not attempt workaround |
| Renamed class also changed API | Runtime fatal at call site | Alias only renames; review signature diffs per entry |
| Stale static alias maps + OPcache | Old name resolves on one node, not another | Always run dump-autoload and reload FPM on deploy |
| Alias collides with Laravel facade alias | Unpredictable class resolution | Collision audit before enabling |
| Alias target removed upstream | Fatal Class not found |
CI test that resolves every alias in the map |
Ramp-up
allow-plugins.dump-autoload step and the vendor-mutability decision — this is where the change actually lands.How can I help you explore Laravel packages today?