erag/laravel-pwa
Laravel PWA adds progressive web app support to Laravel 8–13 projects: auto-generated manifest and service worker, a configurable add-to-home-screen prompt, and Blade directives. Works with Blade, Livewire, Vue 3, and React; requires HTTPS.
Architecture fit. The package is a thin convenience layer, not a platform: it generates a static manifest.json and service worker into public/, exposes two Blade directives (@PwaHead, @RegisterServiceWorkerScript), a PWA facade for runtime manifest updates, and a logo-upload helper. It introduces no runtime services, queues, migrations, or middleware, so it does not alter the application's architecture. That is the right shape for what it does, but it also means the package's value is "saves ~150 lines and a config file" — a build-vs-buy decision a TPM should make explicitly rather than default into.
Integration feasibility. Low-effort: composer require, one command (erag:install-pwa), two directives in the layout. Claimed Laravel 8–13 support means it will not gate a framework upgrade. Compatibility with Livewire/Vue/React is structural rather than tested — the directives only emit HTML/JS, and there is a livewire-app config flag plus a v1.8.0 "Livewire app error fix," which signals that Livewire's SPA-style navigation is a known friction point rather than a solved one. Vue/React support is effectively "it works if your index HTML is server-rendered by Blade," which excludes SPA deployments using a separate frontend build.
Technical risk. The material risks are concentrated in three areas:
sw.js, not the docs.public/. The facade writes manifest.json at request time and processLogo() overwrites public/logo.png. This conflicts with immutable/read-only filesystems, ephemeral containers, and horizontally scaled deployments (write lands on one node, siblings drift). It is also a fixed, unconfigurable filename — a collision hazard for multi-brand or multi-tenant apps with an existing logo.png.NOASSERTION while the README claims MIT; the discrepancy must be closed by legal before adoption. The package is single-maintainer with 0 dependents — no downstream field validation, no bus factor. Maturity signals are README and releases only; there is no evidence of a test suite or CI. The team would be the first real verifier.Secondary risks: opinionated defaults likely to ship unedited (display: 'fullscreen' rather than standalone, app name "Laravel PWA", short name "LPT"); an unauthenticated-capable file-upload helper that must be reviewed for validation and route protection; and a debug console-logging toggle.
Key questions.
manifest.json and logo.png writes required for our use case, or can we go read-only and commit the artifacts instead?Stack fit. Good fit for a monolith serving Blade-rendered HTML: Laravel 8–13, Livewire or server-rendered Vue/React islands. Poor fit for decoupled SPA frontends (Vite + Vue/React SPA with a token-auth API), where the directives never reach the rendered shell and PWA wiring belongs in the frontend build (vite-plugin-pwa), not in PHP.
Migration path. Treat this as additive with a deliberate exit hatch. Pin ^2.1 in composer.json and rely on the lockfile; do not float. Do not let PWA::update() and PWA::processLogo() spread beyond a single settings controller and service — wrap them behind an internal PwaSettings interface so the package is one adapter swap away from removal. Prefer committing generated manifest.json/sw.js and configuring via config/pwa.php + erag:update-manifest in CI, avoiding the runtime-write path entirely.
Compatibility checks. Confirm the Laravel version matrix against our actual constraint; confirm PHP version support; confirm the service worker is served from the app root so its scope covers the whole origin (a SW served from a subpath silently limits scope); confirm HTTPS termination at the edge still presents a secure context to the browser.
Sequencing.
sw.js and the manifest generator; legal clears the license; security reviews processLogo() validation and any published route.Maintenance. Low code surface, but maintenance is not zero: the package is pre-3.x, jumped v1→v2 within a year, and ships frequent small releases (v2.1.0 for iOS install prompts, v2.1.1 doc fixes). Budget a recurring dependency-review slot and expect to read diffs rather than trust release notes. Because we would be among the earliest adopters, we should assume we will find the bugs and upstream them.
Support. Effectively community-only: single maintainer, GitHub issues, no vendor SLA, no paid support. Internal ownership must be assigned — a named engineer responsible for the service worker and manifest — otherwise PWA breakage will be diagnosed by whoever notices the install prompt stopped appearing.
Scaling. Runtime cost is nil: static files served from public/, CDN-friendly. The scaling concern is deployment topology, not load — the write paths degrade under multi-instance and read-only filesystems. Committing artifacts and generating in CI removes this class of problem entirely and is the recommended posture.
Failure modes to instrument.
logo.png overwrite clobbering an existing brand asset.display mode not meeting browser install criteria.manifest.json and sw.js post-deploy and asserts a version marker; smoke-test the install prompt in a release checklist.Ramp-up. Very shallow — an engineer can integrate in under an hour from the README. The ramp-up cost sits on the verification side: someone must understand service worker lifecycle and cache invalidation to operate this responsibly, and that knowledge is not in the package. If no one on the team owns that, budget for it before adoption.
Recommendation. Conditional adopt for Blade-rendered surfaces where PWA is a nice-to-have (installability, offline page), with committed artifacts and CI generation rather than runtime writes, contingent on the license clearing and the service worker audit passing. For a core product surface where PWA behavior is user-facing and revenue-relevant, favor owning a small in-house implementation — the dependency's convenience is modest relative to the verification and stewardship burden it transfers to us.
How can I help you explore Laravel packages today?