codezero/composer-preload-files
codezero/composer-preload-files is a Composer plugin that generates and manages PHP preload file lists, helping Laravel and PHP applications warm OPcache at startup for faster boot and response times.
Install (build-time dependency, not runtime):
composer require --dev codezero/composer-preload-files
Because this is a Composer plugin, you must also whitelist it on Composer 2.2+:
{
"config": {
"allow-plugins": {
"codezero/composer-preload-files": true
}
}
}
Register your preload files in the root composer.json. The plugin reads a list of paths (relative to the project root) that should be required before any dependency's autoload.files entries:
{
"extra": {
"preload-files": [
"bootstrap/preload.php"
]
}
}
First use case — force a definition before a vendor file loads. Common shape:
// bootstrap/preload.php
if (! function_exists('some_vendor_helper')) {
// or a constant, class_alias, polyfill, etc.
}
Verify it worked:
composer dump-autoload -v
grep -n "preload" vendor/composer/autoload_files.php
Open vendor/composer/autoload_files.php — your file's hash key should appear at the top of the returned array, above vendor entries. That generated file is where the ordering lives; it is the single source of truth for "did this actually apply."
First look points:
vendor/composer/autoload_files.php (result of the plugin).vendor/codezero/composer-preload-files/src/ — it's a small hook on post-autoload-dump, so reading it takes five minutes and removes all guesswork about the exact config key in your version.extra key name if your installed version differs from the snippet above.Pattern 1 — Pre-empt a vendor class_alias / polyfill.
When two packages fight over a class name, or a dependency does class_alias(Foo::class, 'LegacyFoo') and you need LegacyFoo to be your own implementation, define your alias first. Preload files are included in registration order, so put the shim in preload-files.
Pattern 2 — Constants and global helpers the vendor file assumes.
Some packages' autoload.files scripts reference constants or helper functions defined elsewhere. Preloading a small bootstrap/preload.php that declares them makes those files safe to include regardless of dependency install order.
Pattern 3 — Deterministic ordering in Docker/CI builds. Treat the plugin as part of the build pipeline. In your Dockerfile:
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --prefer-dist
COPY . .
RUN composer dump-autoload --no-dev --optimize --classmap-authoritative
The dump-autoload re-runs the plugin hook, so the ordering is regenerated on every build rather than relying on a committed vendor/ directory.
Pattern 4 — Environment-conditional bootstrap.
A single bootstrap/preload.php that switches on APP_ENV or getenv('CI') keeps the config list short. Keep side effects idempotent (function_exists, defined, class_exists) so double-inclusion in tests or composer dump-autoload re-runs is harmless.
Pattern 5 — Keep the plugin out of require-dev if production installs need it.
If --no-dev production installs still need the preload ordering, move the plugin to require. It only runs during dump-autoload, never at request time, so the runtime cost is zero — but the dependency must be present when Composer executes the hook.
Integration tip. Pair with composer config sort-packages true and keep the extra.preload-files list alphabetized/grouped by concern (shims/, polyfills/, bootstrap/) so diffs stay reviewable.
allow-plugins will bite you silently. On Composer 2.2+ the plugin is disabled until whitelisted. Symptom: no error, but autoload_files.php is unchanged. Always confirm with composer dump-autoload -v and inspect the generated file.vendor/composer/autoload_files.php is regenerated on every install/dump-autoload. If you hand-edit it, the fix is gone next run. Never commit changes to it — commit the extra.preload-files config instead.include/require targets. It does not affect PSR-4/PSR-0 resolution or classmap order. If you needed class definition ordering, this is the wrong tool.composer.json. Absolute paths and ~ won't behave as expected; symlinked monorepo paths are resolved from the package root, so test in the same layout your CI uses.artisan). A die(), an echo, or a slow file_get_contents in a preload file affects everything.autoload_files.php, both will attempt the edit on post-autoload-dump. Verify final order after adding any second plugin; conflicts are silent, not thrown.--classmap-authoritative is fine — this plugin only touches the files map, so authoritative classmaps don't disable it. But --no-autoloader obviously does; don't use it in a build that relies on the preload."codezero/composer-preload-files": "^1.0", and after any Composer major upgrade, re-run dump-autoload and diff autoload_files.php against a known-good copy. The plugin hook API surface is stable, but it has no downstream users validating breakage for you.allow-plugins? (2) plugin in require/require-dev as appropriate for the build? (3) config key spelled per README? (4) file path exists relative to root? (5) run composer dump-autoload -v and inspect vendor/composer/autoload_files.php for your hash key at the top.post-autoload-dump script of your own (~20 lines rewriting autoload_files.php). Knowing that is the best insurance against an abandoned package.How can I help you explore Laravel packages today?