zoerb/filerevbundle
zoerb/filerevbundle is a Symfony bundle for file revisioning and cache busting. It helps generate revisioned references to static assets so browsers fetch updated files after changes, simplifying asset versioning in Symfony applications.
Architecture fit — the premise is wrong, and that is the headline finding. zoerb/filerevbundle is a Symfony 2 bundle, not a Laravel package. It ships the Symfony bundle conventions — a DependencyInjection/*Extension class reading a Configuration tree, service definitions wired via Resources/config/services.yml, and (typically) a console command plus a Twig helper. None of that is portable to Laravel: there is no AppKernel, no container extension registration, no Bundle class contract, no services.yml loader that Laravel's container will honour. So the realistic integration surface in a Laravel application is zero lines of installable code and 100% conceptual port of the file-revisioning strategy (hash a file's contents, rename or copy it to a hashed path, emit a manifest mapping logical → hashed names, resolve those names in templates). That is a ~100–200 line reimplementation, not an integration.
Integration feasibility. Low as a package; moderate as a design reference. The functional scope is genuinely narrow — content-hash or mtime-based asset versioning with a manifest — which is exactly why it is easy to reimplement and equally why it has no moat. Laravel already has this solved natively: laravel-mix with mix()/mix-manifest.json for older apps, and Vite with @vite/Vite::asset() as the default in Laravel 9+ (vite.config.js emits public/build/manifest.json, and Laravel's Vite integration already resolves hashed filenames). Modern Symfony also superseded the approach internally via JsonManifestVersionStrategy in symfony/asset. Both ecosystems independently converged on "manifest + framework helper," which means the package's value today is documentation of a pattern, not code you want in a dependency tree.
Technical risk. Effectively maximum on the maintenance axis and near-zero on the blast-radius axis. Signals: 2 stars, 0 dependents, last release 2016-01-09, composite score 0.23. A 2016 release implies a composer.json constraining php and symfony/symfony (or symfony/framework-bundle) to the 2.x/3.0 era; on any PHP 7.4/8.x runtime Composer will either refuse to resolve or force --ignore-platform-reqs, and Symfony 2 reached end-of-life in November 2018. There is no upstream security response, no CI, and no issue triage. The mitigating factor is that asset filename hashing has no runtime authority — no database access, no auth, no network egress, no deserialization — so the CVE surface is small. The real risk is silent obsolescence, not exploitation. Licence should be verified (probably MIT, per the author's other work) before any code is copied rather than depended upon.
Key questions for the requester. (1) What problem is being solved — browser cache-busting for static assets on a Laravel app, or porting an existing Symfony 2 codebase? The answer changes everything. (2) Is there a hard requirement to reuse this package specifically, or was it surfaced by a keyword search for "filerev"/"asset versioning"? (3) What does the actual asset pipeline look like today — Mix, Vite, Webpack, or manual filemtime() calls in Blade? (4) Is there an existing public/build/manifest.json or mix-manifest.json? (5) Who owns the build toolchain — frontend or backend — because this decision belongs to whoever owns the bundler config. I would treat "adopt zoerb/filerevbundle" as a request that has already been mis-scoped, and re-open it as "we need content-hash asset versioning in Laravel."
Stack fit. Poor as a dependency, good as a pattern source. Concretely: do not add zoerb/filerevbundle to composer.json in a Laravel project. There is no ServiceProvider to auto-discover, no config/filerev.php merge hook, no Artisan command registered, and the bundle's Twig helper ({{ filerev('app.css') }}) has no Blade equivalent shipped. Installing it produces at best a dead vendor directory and at worst a platform-requirement failure that blocks unrelated composer update runs.
Migration path. Two legitimate routes, and I would pick based on Laravel version:
npm install, vite.config.js with laravel-vite-plugin, @vite(['resources/css/app.css', 'resources/js/app.js']) in the Blade layout, and Vite::asset() for dynamic paths. The manifest and hash semantics are identical to what filerev was doing in 2016; the difference is that it is maintained, ships a dev server with HMR, and is the documented default. This is a delete-the-problem outcome, which is the best TPM outcome.mix.version() plus mix() in Blade is the port. Keep it; do not migrate toolchains solely because this evaluation surfaced.If a manifest resolver is genuinely needed outside a bundler (e.g. assets built by an external pipeline, or a Blade component resolving hashed names from a JSON map), implement it as a small AssetManifestServiceProvider + asset_rev() helper that reads public/build/manifest.json, caches the decoded array in the container as a singleton, and throws on a missing key rather than falling back to the unhashed path. That is the entire value of the original package, ported in an afternoon and testable with a single fixture manifest.
Compatibility. Nothing about the original constrains a Laravel port — the algorithm (read file, md5_file or sha1_file, rename to name.<hash8>.<ext>, write manifest JSON, rewrite references) is version-agnostic. The only compatibility work is choosing the hash length and whether references are rewritten at build time (filerev's approach) or resolved at request time via manifest lookup (Vite/Laravel's approach). Prefer the latter: it composes with a CDN, survives partial deploys, and avoids the rewrite pass.
Sequencing. (1) Confirm the actual requirement in writing — asset cache-busting, not this package. (2) Inventory the current pipeline and whether a manifest already exists. (3) Stand up the native solution in a non-production environment and diff the resulting HTML against current output — the acceptance test is "hashed URL in the rendered page, and a 200 from the CDN." (4) Delete any exploratory filerev work. (5) Only if the bundler cannot be touched, write the ~150-line manifest resolver and back it with a feature test. Budget this as one sprint-day of engineering, not a dependency-evaluation ticket — the package does not warrant further due diligence.
Maintenance. Unmaintained since January 2016, with 2 stars and 0 dependents, is about as clear an abandonment signal as the ecosystem produces. There is no release train, no PHP 8 compatibility work, no Symfony 4/5 migration, and no evidence anyone would notice a breaking change. Adopting it transfers 100% of maintenance to your team on day one, while still carrying the coordination cost of a third-party dependency — the worst of both worlds. Copying the algorithm removes the dependency but leaves you owning the same code; using Vite removes the dependency and the code.
Support. None. No issue triage, no security advisories, no maintainer to escalate to, no vendor relationship. Internal support load is low in absolute terms because the domain is simple and failure modes are loud and localised, but there is no external backstop if it misbehaves on a PHP upgrade.
Scaling. The approach scales fine technically — manifest lookup is O(1) with a cached array and adds no request-path cost beyond a single associative-array read. It scales badly organisationally: every new developer onboarding to the codebase has to be told "ignore this vendor, it's a 2016 Symfony bundle we ported half of," which is exactly the kind of accumulated explanation debt that erodes trust in the dependency graph. Zero dependents also means no peer-reviewed usage to lean on when something looks wrong.
Failure modes. (1) Manifest drift — a build writes hashed files but the manifest is stale or not deployed, producing 404s on every hashed asset; this is the dominant real-world failure and is a deploy-ordering problem, not a code problem. (2) Silent fallback — resolvers that return the unhashed path when a key is missing mask the drift until a browser serves a stale cached asset, which is worse than a hard failure. Fail loudly. (3) Rewrite-pass corruption — build-time reference rewriting (filerev's model) can miss references in JS string literals, inline styles, or dynamically constructed URLs; manifest lookup at render time avoids this class entirely. (4) Partial deploy — old HTML referencing new hashes, or vice versa; mitigated by deploying assets before HTML and keeping hashed filenames immutable. (5) Platform/lockfile deadlock — the 2016 constraints blocking composer update for unrelated packages.
Ramp-up. Trivial on the concept, and that is the point: any mid-level engineer understands content-hash cache-busting in ten minutes, and the Vite docs are the canonical reference. There is no training cost to "not using this package." The only ramp-up worth scheduling is the one-day spike to stand up Vite (or Mix) and validate the rendered-output diff. Recommendation: do not adopt zoerb/filerevbundle — close the request as superseded, document the manifest-strategy rationale for the record, and route the underlying need to the bundler your framework already ships.
How can I help you explore Laravel packages today?