A small, framework-light cookie-consent toolkit for React and Next.js. Config-driven, i18n-agnostic, SSR-safe, and built with GDPR in mind — including Do Not Track and Global Privacy Control support.
▶ Try the live demo on StackBlitz
import { ConsentProvider, CookieBanner } from "consentium";
import "consentium/styles.css";
<ConsentProvider config={consentConfig}>
{children}
<CookieBanner />
</ConsentProvider>;Most consent libraries are either heavyweight SaaS scripts or barely-styled checkboxes. consentium is the middle ground: one provider, one banner, one stylesheet, and a tiny store you drive from your own code. You decide what each category gates — the kit just records the decision and tells your app about it.
- Category-based consent —
essential(always on) plus any optional categories you define (analytics, marketing, …). - Accept all / reject all / per-category — the three flows GDPR expects, with reject one click away, side by side with accept.
- SSR-safe — renders the same on server and client, then resolves from
localStorageafter mount, so there is no hydration mismatch. - Do Not Track + Global Privacy Control — categories you flag are forced off when the browser signals a privacy preference, even if toggled on.
- Policy versioning — bump
policyVersionand returning visitors are re-prompted, keeping their prior choices as defaults. - i18n-agnostic — English copy ships by default; pass a
copyobject to translate or reword everything. Wire it to next-intl, react-i18next, anything. - Themeable with CSS variables — every token is a namespaced
--ck-*custom property; no build-time CSS-modules needed. - No runtime dependencies — just React as a peer. 3.3 KB min+gzip for the full UI, or 1.1 KB for the headless core (see Bundle size).
- Reactive — subscribe to consent changes to start/stop scripts live within a session.
Important
consentium is engineering tooling, not legal advice. It gives you the mechanism for lawful consent; you are responsible for the categories you declare, the copy you write, and whether your setup meets the rules in your jurisdiction. See docs/gdpr.md.
React is the only peer dependency; there are no runtime dependencies. Sizes
below are the published build bundled with React externalized
(esbuild --minify, then gzip):
| Import | Min + gzip |
|---|---|
consentium — full UI (provider, banner, hooks, disclosures) |
3.3 KB |
consentium/core — headless store only, no React |
1.1 KB |
Tree-shakeable and side-effect-free apart from the stylesheet, so you only pay for what you import.
consentium is intentionally small: a client-side React banner plus a consent
signal in localStorage, no backend and no runtime dependencies. That narrow
scope is the point — which also means other tools are a better fit for some
needs, and it's worth being upfront about that.
- c15t is a full consent platform: an optional self-hosted backend or managed cloud (consent.io), server-side consent records, jurisdiction detection, IAB TCF 2.3, and prebuilt script integrations. Reach for it if you need an audit trail of who consented to what, you're doing adtech / TCF, or you'd rather not wire integrations yourself.
- SaaS consent managers (Cookiebot, Osano, CookieYes, …) give you a hosted script, a dashboard, and managed scanning — at the cost of a third-party request and a heavier payload. Reach for one if you want compliance handled as a service rather than as code you own.
- consentium fits when you want a tiny, SSR-safe banner and a consent signal you own outright, nothing to host, and you're happy to decide yourself what each category gates — it gives you the mechanism and you wire the scripts. It does not do server-side consent records, jurisdiction detection, or IAB TCF, and Google Consent Mode v2 is a documented recipe rather than something built in.
npm install consentiumOr straight from GitHub (builds itself on install via the prepare script):
npm install github:ivandrenc/consentium
# or pin a tag: npm install github:ivandrenc/consentium#v0.1.0Requires React 18 or 19. The published npm package ships prebuilt, so it installs on any supported Node. Building from source (the GitHub install or a local clone) needs Node 20+.
// consent.config.ts
import type { ConsentConfig } from "consentium";
import { presetCategories } from "consentium";
export const consentConfig: ConsentConfig = {
productName: "Acme",
storageKey: "acme_consent",
policyVersion: 1,
routes: { cookies: "/cookies", privacy: "/privacy" },
categories: [
presetCategories.analytics, // flagged respectDoNotTrack
presetCategories.marketing,
],
};import { ConsentProvider, CookieBanner } from "consentium";
import "consentium/styles.css";
import { consentConfig } from "./consent.config";
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<ConsentProvider config={consentConfig}>
{children}
<CookieBanner />
</ConsentProvider>
);
}The banner shows only while the visitor hasn't decided. After they choose, it disappears and the choice is persisted.
This is the part that actually matters for compliance — nothing tracking should run before consent. Read the store and subscribe to changes:
"use client";
import { useEffect } from "react";
import { useConsent } from "consentium";
export function Analytics() {
const { store } = useConsent();
useEffect(() => {
const start = () => {
if (store.hasConsent("analytics")) loadAnalytics(); // your loader
};
start();
return store.subscribe(start); // react to later opt-in
}, [store]);
return null;
}See docs/recipes.md for ready-made Google Analytics, Google Tag Manager (Consent Mode), and PostHog gates.
Drop a settings link in your footer — withdrawing consent must be as easy as giving it:
import { CookieSettingsLink } from "consentium";
<footer>
<CookieSettingsLink /> {/* re-opens the banner */}
</footer>;| Guide | What's in it |
|---|---|
| Configuration | Every ConsentConfig field, categories, processors, cookies |
| Theming | The --ck-* token list and a dark-mode recipe |
| Next.js | App Router setup, <Link> integration, the /cookies page |
| Internationalization | Translating copy; a next-intl example |
| Recipes | Gating GA4, GTM Consent Mode, and PostHog |
| GDPR notes | What the kit does and does not do for you |
| API reference | Every export, hook, and store method |
A runnable Next.js App Router example lives in
examples/nextjs-app-router.
Override any --ck-* variable at a scope that wraps the banner:
:root {
--ck-color-accent: #4f46e5;
--ck-color-accent-ink: #ffffff;
--ck-radius-lg: 12px;
--ck-font-display: "Your Serif", Georgia, serif;
}Full token list and a dark-mode example: docs/theming.md.
The store is framework-agnostic. Import from consentium/core to use it in
Vue, Svelte, or vanilla JS:
import { createStore } from "consentium/core";
const store = createStore({
storageKey: "acme_consent",
policyVersion: 1,
categories: [{ id: "analytics", label: "Analytics", description: "…" }],
});
store.subscribe((rec) => console.log(rec));
if (store.hasConsent("analytics")) {
/* … */
}Contributions are welcome — see CONTRIBUTING.md. The gates
are npm run typecheck, npm test, and npm run format:check; all three run
in CI.
MIT © Ivan Naranjo