innocenzi/laravel-vite
Innocenzi Laravel Vite integrates the Vite frontend build tool with Laravel, offering Blade directives, helpers, config publishing, and hot module replacement for a fast, modern asset pipeline.
Architecture fit. innocenzi/laravel-vite sits at the outer edge of the application — a service provider that registers Blade directives (@vite, @viteReactRefresh), a Vite facade, a manifest reader, and a dev-server client that reads public/hot. Coupling to domain code is essentially nil; coupling to the build toolchain and to every Blade layout is total. That is a favourable seam for replacement, but it also means the package's assumptions about Vite's manifest schema and dev-server handshake are load-bearing on every page render.
Integration feasibility. Mechanically trivial — one composer require, a published config/vite.php, and a matching npm plugin. Strategically infeasible: the package is archived and its last release (2023-02-16) predates Vite 5. The upstream successor is first-party and already in the framework: Laravel 9.19+ ships a Vite class, an @vite Blade directive, and the laravel-vite-plugin npm package that supersedes this dependency entirely. Adopting this package today means adopting a dead end with a known, free replacement.
Technical risk — high. Four concrete exposures:
@vite. Whichever wins is load-order dependent — a silent, environment-specific failure mode.Key questions for the team.
@vite / @viteReactRefresh, the Vite facade, and config/vite.php keys — including package/third-party views you don't own.Verdict. Score 2.475 with an archived flag is disqualifying for greenfield. The only defensible posture is contain and exit: freeze the version, document it as technical debt with an owner and a date, and schedule migration. If the answer to question one is "Laravel ≥ 9.19", this is a one-sprint cleanup, not a decision.
Stack fit. The package fits exactly one window: Laravel 8.x through ~9.18 with Vite 2–4. Outside that window it is either redundant (Laravel ≥ 9.19) or unsupported (Vite 5+). Treat the compatibility statement as a hard gate, not a preference.
Migration path (the recommended "integration" is removal).
laravel-vite-plugin; rewrite vite.config.js entry points, build.outDir, build.manifest, aliases, and any server.* proxy/host settings that lived in config/vite.php.config/vite.php and the service provider registration; let the framework's Vite class take over.@vite(['resources/css/app.css', 'resources/js/app.js']) calls are unchanged; @viteReactRefresh becomes @viteReactRefresh from the framework — but verify argument shape, hot-file semantics, and any @vite calls that passed a custom build directory.public/build, verify manifest keys, and ensure public/hot is git-ignored and absent from the deploy artifact.Vite::asset(), Vite::content(), app(Vite::class) — that the directive swap won't catch.Compatibility matrix to validate before cutover. Laravel 9.19/10/11/12 × Node 18/20/22 × Vite 5/6/7, plus your CI image and any Docker build stage. Pin Node in CI and in the runtime image; a floating Node tag is the most common cause of "works locally, fails in pipeline" during this migration.
Sequencing. Inventory → freeze current versions and add the dependency to the debt register (day 0–2) → build the migration on a branch with the new plugin and framework directives (day 3–5) → parallel-verify dev server, HMR, SSR if present, and production build/view:cache (day 5–7) → cut over behind the normal release train → delete the package, config, and any shims; confirm composer why shows no residual dependents.
If migration must be deferred (e.g. an inherited Laravel 8 app): pin the exact package version and the exact Vite version in lockfiles, add a CI assertion that fails on drift, and set an explicit review date. Do not carry it into any new project.
Maintenance. Effectively infinite cost with zero upstream return: you own the code the moment you install it. Budget a fork if you need even a one-line patch, because PRs will not be merged. The realistic maintenance plan is a dated exit, not stewardship.
Support. No vendor, no maintainer, no release notes going forward. Internal knowledge will concentrate in whoever ran the original setup. Decaying Stack Overflow and blog answers will increasingly describe the first-party package instead, which is a subtle onboarding hazard — engineers will find advice that doesn't apply to this dependency.
Scaling. Runtime cost is negligible: a manifest JSON read plus a file_exists check on public/hot, both cacheable and amortised across requests. There is no horizontal-scaling concern. The scaling risk is in the build path — CI concurrency, artifact size, and CDN cache-key churn if the asset hashing strategy ever diverges from what the manifest advertises.
Failure modes to instrument.
public/hot in production — the classic. Asset URLs point at localhost:5173, every page 404s its CSS/JS. Mitigate with a deploy-time assertion that public/hot does not exist in the release artifact, and an entry in the post-deploy smoke test.public/build wasn't shipped or view:cache ran against an old manifest — surfaces as a 500 on every route. Alert on it explicitly.Ramp-up. The package is small and its surface is familiar, so a mid-level engineer can operate it in under a day. The cost is not comprehension, it is confidence: no upstream, no roadmap, and every upgrade conversation ending in "we'll have to fork it." For a TPM, the real operational impact is a standing tax on every framework and build-tool upgrade discussion until the dependency is removed — which is the argument for removing it now, while the replacement is a config file and a handful of Blade lines rather than a blocking constraint on a Laravel major.
How can I help you explore Laravel packages today?