ongr/cookies-bundle
ONGR Cookies Bundle is a Symfony bundle for GDPR-friendly cookie consent: define cookie categories, render a consent banner, store visitor choices, and conditionally load analytics or tracking scripts only after users opt in.
Architecture fit — low, with a category mismatch. ongr/cookies-bundle is a Symfony bundle, not a Laravel package. It is registered through AppKernel/bundles.php and configured under an ongr_cookies: key in Symfony YAML, and it models each cookie as a DI service (tagged, injected via the container) with a CookieManager/Cookie model plus Twig helpers for consent checks. Laravel has no bundle system, no AppKernel, and no tagged-service cookie registry out of the box. The only genuine overlap is that Laravel's HTTP layer is built on symfony/http-foundation, so the underlying Cookie value object and CookieJar concepts map cleanly — the idea transfers, the code does not.
Integration feasibility — near zero as a dependency; moderate as a reference design. Expect composer require ongr/cookies-bundle to fail resolution in a modern Laravel app: a 2016-06-06 release implies constraints around symfony/framework-bundle ~2.3|~3.0 and PHP 5.5/7.0, which conflict with Laravel 9–11 (PHP 8.1–8.4, Symfony 6/7 components). Even if forced through with --ignore-platform-reqs, the bundle's compiler passes and service definitions target Symfony's DI semantics of that era, and Laravel's container is not a drop-in host for a Bundle subclass. Realistic path: read the source (likely a few hundred LOC of model + manager + Twig extension + config tree) and reimplement natively in ~2–5 engineering days.
Technical risk — high, concentrated in staleness rather than complexity. The logic is small and MIT-licensed, so IP risk is nil. The risks are: (1) unmaintained — ten years without a release, no security response path, 4 stars and 0 dependents means effectively no community scrutiny; (2) cookie security defaults — 2016-era code predates SameSite support in setcookie() (PHP 7.3) and modern __Host-/Partitioned guidance, so flags will almost certainly need hardening; (3) consent semantics — if the bundle's consent gate is bypassable by a direct set, it fails ePrivacy/GDPR intent regardless of code quality; (4) hidden coupling to ongr/* sibling packages and old Symfony event/listener wiring that will not translate.
Key questions for the team:
spatie/laravel-cookie-consent, whitecube/laravel-cookie-consent, or a first-party CookieJar wrapper)?Verdict: treat ongr/cookies-bundle as documentation of a pattern, not a dependency. Score 0.55 with no dependents and a 2016 last release is consistent with "conceptually useful, operationally dead."
Stack fit — partial, at the component level only. Target stack is assumed Laravel 10/11 on PHP 8.2/8.3. Laravel ships symfony/http-foundation and symfony/finder/console transitively, so the Cookie object model is already present. Map the bundle's concepts onto Laravel primitives:
| Bundle concept (Symfony) | Laravel equivalent |
|---|---|
| Cookie defined as tagged DI service | Entry in config/cookies.php array (key, category, lifetime, flags) |
CookieManager service |
Singleton CookieRegistry/CookieManager bound in a service provider |
Bundle config tree (ongr_cookies:) |
config/cookies.php + mergeConfigFrom |
Twig cookie_* helper/functions |
Blade directives (@cookieconsent('analytics')) + a cookie() helper |
| Request/response listener attaching consent state | Global or route middleware |
| Consent persistence | Dedicated first-party cookie + optional session fallback |
Migration path — do not install; transcribe. Concretely:
composer require in a throwaway branch only to inspect vendor/ongr/cookies-bundle source and confirm the API surface; discard afterwards.CookieDefinition (name, category, lifetime, secure, httpOnly, sameSite), CookieRegistry (reads config, exposes all(), byCategory(), isAllowed(string $name)).CookieConsentMiddleware that hydrates consent state from the consent cookie into the request and exposes it via a Consent singleton scoped per request.cookies() helper; keep the public API names close to the original to shorten review.SameSite=Lax (or Strict where safe), Secure in non-local environments, HttpOnly for everything except values JS must read, and consider __Host- prefixes for security-critical cookies.!isAllowed('analytics'), the cookie must never be attached to the response, not merely hidden in markup.Compatibility notes. Verify against Laravel's encrypted-cookie middleware: cookies registered here that must be JS-readable need to be in the EncryptCookies exception list, and any cookie set outside the response object will not be encrypted/queued correctly. Watch the 4 KB per-domain cookie budget if the registry grows. Confirm config:cache and route:cache compatibility (no closures in config, no runtime container lookups during boot).
Sequencing.
Maintenance — the dominant cost. There is no upstream to track; with 4 stars, 0 dependents, and no release since 2016, the project should be considered archived. Any code we adopt becomes our fork with our name on it. Budget a nominal 1–2 days per year for dependency hygiene and, more importantly, plan for the compliance surface (cookie categories, vendor lists, regional rules) to change annually — that churn is the real recurring cost, not the code.
Support. No maintainer triage, no CVE feed, no upgrade path. composer audit and Dependabot provide zero coverage if the package is never installed, and false comfort if it is. Internal ownership must be explicit: one named engineer, one backlog item, documented in the repo README.
Scaling. Runtime cost is negligible — a config array lookup and a few header writes per request; it will never be a throughput bottleneck. The scaling concerns are elsewhere: (1) header size against the 4 KB per-domain browser limit as the cookie inventory grows; (2) cache variance — if consent state is rendered server-side into cached HTML, you need Vary: Cookie or edge-side handling, or users will see each other's consent banners; (3) multi-tenant/multi-domain setups need per-host registry scoping.
Failure modes to design against.
setcookie() or JS outside the registry — enforce with a CI response-header scan.Secure/SameSite after a refactor — assert flags in feature tests, not just presence.Secure accidentally enabled locally, or disabled in production via a misconfigured env var.EncryptCookies, or vice versa.Ramp-up. Low to understand, moderate to own. A mid-level Laravel engineer needs roughly half a day to read the reference source and grasp the pattern, and 2–5 days to produce a reviewed, tested native implementation including the consent gate and hardening. No Symfony-specific expertise is required if the team commits to the reimplementation route; requiring engineers to learn Symfony 2 bundle conventions to maintain a 2016 artifact would be a poor allocation of ramp-up budget. Choose the native port and keep the pattern, not the package.
How can I help you explore Laravel packages today?