genealabs/laravel-caffeine
Laravel Caffeine keeps user sessions alive by pinging your app with a lightweight AJAX heartbeat, preventing session timeouts and lost form data when users are inactive. Easy to install and configure for Laravel apps.
Architecture fit. genealabs/laravel-caffeine is a deliberately narrow, single-responsibility dependency: a middleware that injects a small inline JavaScript snippet into HTML responses, plus a synthetic GET /caffeine route that touches the server-side session so a long-idle form still passes CSRF validation at submit. There is no schema, no migration, no queue worker, no external service, and no coupling to our domain model. It lands entirely inside Laravel's HTTP middleware stack and is removable without a data change or a cross-service release. From a delivery-risk standpoint, that is close to the floor for a third-party package.
Integration feasibility. Registration is idiomatic Laravel: auto-discovered service provider, publishable config, auto-registered route returning 204, snippet injected automatically. Realistic engineering effort is under a day for a Laravel-fluent engineer including verification. The friction is environmental rather than code — Content-Security-Policy headers that block inline scripts, full-page caches or CDNs that would store a session-bearing response, reverse proxies or WAFs that drop the keep-alive GET, and session drivers whose expiry semantics differ from the local file driver used in development.
Technical risk, ranked by likelihood of hurting us:
illuminate/* constraint moved rather than widened. That would make this release a rider on a Laravel 13 upgrade, not a standalone bump. If we are on 11 or 12, we must pin ^12.0.3 explicitly so a routine composer update cannot drag the framework forward. This is the single fact to confirm before scheduling anything.Route facade import fix — and it landed in a major, which suggests the preceding minor line carried an untested code path. Argument for pinning exact versions rather than floating.Key questions for engineering before commitment.
12.0.3 → 13.0.0 diff limited to the constraint plus the import fix, or is there a documented upgrade guide implying more?Stack fit. Relevant only where we render server-side HTML forms protected by session-backed CSRF and where a user plausibly holds a page open longer than session.lifetime (default 120 minutes). That is long-form intake, multi-step onboarding, complex settings, uploads, and admin data-entry. It is not relevant to API-only services or stateless token-refresh SPAs. Scope the first enablement to those surfaces rather than switching it on globally.
Migration path.
^12.0.3 explicitly and remove any floating constraint. Same-day, reversible, zero behaviour change.session.lifetime rather than accepting the packaged default, so the two cannot drift apart in a future tuning pass.Compatibility gates. Three checks before first production enablement: CSP must permit the injected script (nonce, hash, or external-script mode); full-page cache and CDN rules must exclude responses carrying the snippet; and the keep-alive route must live in the same session/auth domain as the forms it protects. Validate on the production session driver — that is the most common place a middleware like this behaves differently than in a local test.
Sequencing. Dependency pin first (immediate, reversible, no behaviour change), then Laravel 13 qualification, then per-surface functional enablement. Keep the framework upgrade and the functional enablement as independently revertible changes; bundling them means a rollback of one forces a rollback of both.
Maintenance. Near-zero ongoing code maintenance — nothing to tune, no data growth, no jobs to monitor. The real cost is version tracking: one package major per Laravel major means this dependency belongs on every framework upgrade checklist, and a lagging release becomes an upgrade blocker. Assign a named owner and record it in the dependency register next to the Laravel version it is pinned against.
Support. Expect low volume concentrated in two ticket shapes: "the form randomly logs me out" (almost always CSP or cache blocking the injected script) and 419s on the keep-alive endpoint itself. Both need a runbook entry so on-call can separate package misconfiguration from a genuine session-store or auth incident — the user-visible symptom is identical.
Scaling. Stateless and per-request. The cost is one extra HTTP request per configured interval per open page, and each of those requests writes to the session backend on a timer. Negligible at our volume, but enabling it broadly on high-traffic anonymous pages raises baseline session-store write load; check headroom before a global rollout.
Failure modes. Three worth naming, all silent: CSP blocks the script (forms render, sessions still expire); a CDN or full-page cache stores a response carrying the snippet (a stale session token is served to other users); the route is unreachable at the edge due to proxy/WAF rules (the ping no-ops). None produce an error the user can see until they lose work, so add monitoring on 4xx rates for the keep-alive route before the first rollout and alert on the endpoint disappearing.
Ramp-up. Low. An engineer familiar with Laravel middleware can own this in an afternoon; the transferable knowledge is CSP and session-driver semantics, not the package itself. Document the pinned version, the config derivation from session.lifetime, and the three compatibility gates in the runbook so the next owner does not rediscover them.
How can I help you explore Laravel packages today?