delight-im/cookie
Modern cookie management for PHP. A clean, secure API for setting, reading, and deleting cookies, with support for SameSite, HttpOnly and Secure flags, cookie prefixes, and session handling—helping you follow browser security best practices without boilerplate.
Architecture fit. delight-im/cookie is a framework-agnostic, dependency-free utility library whose surface is essentially two classes: a static Cookie facade over PHP's native setcookie() (adding first-class support for SameSite, HttpOnly, Secure, path/domain/expiry normalization, and a fluent option array), and a Session helper that centralizes session cookie hardening. That is a horizontal capability, not a vertical one — it does not participate in routing, DI, middleware, response objects, or PSR-7/PSR-15. For a Laravel codebase the architectural fit is therefore poor by default and good only at the periphery: it is a reasonable choice for cookie handling inside standalone PHP scripts, legacy non-framework services, CLI-invoked webhooks, or a package that must remain framework-independent. Inside a Laravel application it creates a second, parallel cookie authority alongside Illuminate\Contracts\Cookie\Factory, the EncryptCookies middleware, and AddQueuedCookiesToResponse, which is an architectural anti-pattern rather than an integration.
Integration feasibility. Mechanically trivial: composer require delight-im/cookie, MIT licensed, no transitive dependencies, no service provider needed, no published config. A spike is a single afternoon. The real feasibility question is why — Laravel already ships equivalent or superior semantics (config/session.php and the cookie config expose secure, http_only, same_site, plus encryption and signing via the web middleware group). Any integration must therefore be justified by a genuine out-of-framework boundary, not by preference.
Technical risk.
${} string interpolation removals, and setcookie() signature behavior changes across 7.3/8.x are all live risks for a thin wrapper. The library also predates browsers' default SameSite=Lax behavior, so its explicit SameSite handling is the main value proposition — and the main thing to regression-test.setcookie() interacts with output buffering and "headers already sent" in ways that are invisible to Laravel's response-centric model.Key questions.
illuminate/cookie + EncryptCookies? If the answer is "none," this is a decline.composer.json constraint cover it?SameSite/session-hardening patterns, write ~40 lines of in-house code)? The latter carries most of the value at a fraction of the TCO.Stack fit. Assume Laravel 9–11 with the standard web middleware group. The package fits only in the following lanes, in descending order of justification:
SameSite/Secure/HttpOnly policy that raw setcookie() calls in scattered legacy files do not.Migration path. If adopted at the periphery: (1) install and pin an exact version; (2) wrap it behind our own thin interface (App\Support\CookiePolicy or equivalent) so the vendor class never appears in application code; (3) for the Laravel-facing side, implement Illuminate\Contracts\Cookie\Factory in the adapter so callers see a familiar contract and we retain a one-file swap-out; (4) migrate one legacy cookie at a time, lowest-risk first (theme/locale preference, referral attribution), never auth or session tokens on the first pass; (5) explicitly do not migrate session handling — leave Session unused unless a standalone service genuinely needs it, and if it does, isolate that service so its session cookie never collides with the Laravel app's cookie name or path.
For the far more likely "reference only" route, the migration is a config change: audit config/session.php and config/cookies-equivalent values, set same_site, secure, and http_only explicitly per environment, and delete ad-hoc setcookie() calls in favor of the framework's queue.
Compatibility. Verify against our PHP matrix before anything else — check the php constraint in composer.json, then run the suite on our oldest and newest supported runtimes with E_ALL and deprecations promoted to errors. Confirm behavior when SameSite=None is requested without Secure (browsers discard the cookie silently; the library cannot save us). Confirm interaction with Laravel's EncryptCookies: cookies set through the package are plaintext; anything reading them from a Laravel request through $request->cookie() will either fail decryption or throw, and cookies set by Laravel will look like garbage to the package. That mismatch is the single most likely production surprise and must be designed out by scoping each jar to distinct cookie names and paths.
Sequencing.
SameSite/Secure behavior matrix across Safari/Chrome/Firefox.Maintenance. The code itself is near-zero maintenance; the dependency is not. Budget an owner, a pinned version, and a standing quarterly check for upstream commits, PHP deprecation notices, and browser SameSite default changes. If the upstream goes quiet for 12+ months — the base rate for single-maintainer libraries — we either accept frozen code (fine, it is small) or fork it (then we own it fully). Either way, write down which one we chose. The 0-dependents figure means package managers and scanner tooling will tell us nothing; our own review is the control.
Support. No vendor, no SLA, no support contract. Internal support means "whoever read the source." That person must be named in the runbook, and the runbook must include the two failure signatures: cookie silently absent from the request, and cookie present but unserializable due to encryption mismatch. On-call triage for this should be a 15-minute decision tree, not an investigation.
Scaling. Technically a non-issue — it is a thin wrapper, no I/O, no state beyond PHP internals. The operational scaling risk is consistency: the moment two cookie mechanisms coexist, every new engineer has to know which cookies go through which path and why. That cognitive tax compounds with headcount far faster than it compounds with traffic. It also complicates CDN/edge cookie handling, domain consolidation, and any future move to a shared parent-domain session — exactly the sort of multi-brand or multi-app consolidation a TPM tends to get asked to plan.
Failure modes.
setcookie() after output has started, producing a warning that a APP_DEBUG=false config suppresses. Symptom: intermittent login loops. Mitigation: assert headers-not-sent in the adapter and log loudly.Lax/Strict. This is the most common real-world regression from cookie work and is invisible to unit tests.Session helper is adopted without matching the rest of the auth design (regeneration on privilege change, absolute and idle timeouts).Ramp-up. Learning the API is under two hours for any PHP developer — the surface is small and the README is adequate for the happy path. The expensive part is the context: cookie scoping, SameSite semantics, encryption boundaries, and our own dual-stack policy. Budget roughly 1–2 days of onboarding for an engineer expected to touch this, most of it spent on our adapter and runbook rather than the vendor code. Document the decision ("used only for X, never for Y") next to the dependency — an undocumented parallel cookie mechanism is indistinguishable from an accident six months later.
Bottom line for prioritization. The low opportunity score is directionally right: this is a commodity capability that Laravel already delivers with encryption, signing, and middleware integration we would otherwise have to reconstruct. Recommend not adopting it as a runtime dependency in the Laravel application; recommend a short (≤2 day) audit against it to validate our SameSite/Secure/HttpOnly posture, plus a narrow dependency only if a concrete out-of-framework PHP surface exists that needs identical cookie semantics.
How can I help you explore Laravel packages today?