@msobiecki/cookie-store
v1.6.0
Published
Typed cookie store API for browser, Express, and Next.js with React hooks support.
Maintainers
Readme
@msobiecki/cookie-store
Tiny, typed cookie API that works across browser, Express, and Next.js.

Features
- One factory to create an adapter-specific cookie store.
- A Promise-based API with get, set, and delete methods.
- Optional React helpers for client-side apps.
Installation
npm install @msobiecki/cookie-storeIf you use the Express adapter, also install cookie-parser:
npm install cookie-parserTo read/write signed cookies in Express, initialize cookie-parser with a secret:
app.use(cookieParser("your-secret"));Quick Start
Browser
import { createCookieStore } from "@msobiecki/cookie-store";
const getCookieStore = createCookieStore({ adapter: "browser" });
const cookieStore = await getCookieStore();
await cookieStore.set("theme", "dark", {
maxAge: 1000 * 60 * 60 * 24,
path: "/",
});
const theme = await cookieStore.get("theme");
await cookieStore.delete("theme");Express
import express from "express";
import cookieParser from "cookie-parser";
import { createCookieStore } from "@msobiecki/cookie-store";
const app = express();
app.use(cookieParser("your-secret"));
const getCookieStore = createCookieStore({ adapter: "express" });
app.post("/theme", async (request, response) => {
const cookieStore = await getCookieStore(request, response);
await cookieStore.set("theme", "dark", {
maxAge: 1000 * 60 * 60 * 24,
httpOnly: true,
signed: true,
path: "/",
});
const signedTheme = await cookieStore.get("theme", { signed: true });
response.json({ ok: true, signedTheme });
});Next.js (App Router)
import { createCookieStore } from "@msobiecki/cookie-store";
const getCookieStore = createCookieStore({ adapter: "next" });
export async function POST() {
const cookieStore = await getCookieStore();
await cookieStore.set("theme", "dark", {
maxAge: 1000 * 60 * 60 * 24,
path: "/",
});
return Response.json({ ok: true });
}React Integration
Use CookieProvider in client components and read/update values with hooks.
"use client";
import {
CookieProvider,
useCookie,
useCookies,
} from "@msobiecki/cookie-store/client";
function ThemeControls() {
const [theme, setTheme, removeTheme] = useCookie("theme", {
maxAge: 1000 * 60 * 60 * 24,
});
const allCookies = useCookies();
return (
<div>
<p>Theme: {theme ?? "not set"}</p>
<button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
Toggle
</button>
<button onClick={() => removeTheme()}>Clear</button>
<pre>{JSON.stringify(allCookies, null, 2)}</pre>
</div>
);
}
export default function App() {
return (
<CookieProvider>
<ThemeControls />
</CookieProvider>
);
}API
createCookieStore
createCookieStore({ adapter: "browser" | "express" | "next" });Returns an async function:
- browser: call with no arguments.
- next: call with no arguments.
- express: call with request and response.
TypeScript overloads return adapter-specific stores:
- browser -> BrowserCookieStore
- next -> NextCookieStore
- express -> ExpressCookieStore
CookieStore
interface CookieStore {
get(name: string): Promise<string | undefined>;
set(name: string, value: string, options?: CookieOptions): Promise<void>;
delete(name: string, options?: CookieOptions): Promise<void>;
getAll(): Promise<Record<string, string>>;
}Notes:
- Browser adapter adds change listeners via subscribeChange and unsubscribeChange.
- Browser adapter uses the Cookie Store API when available and falls back to document.cookie.
CookieOptions
interface CookieOptions {
path?: string;
domain?: string;
expires?: Date;
maxAge?: number;
sameSite?: "strict" | "lax" | "none";
partitioned?: boolean;
secure?: boolean;
}maxAge is in milliseconds.
Express Adapter Options
ExpressCookieStore extends the base store with signed-cookie reads and writes.
type ExpressCookieReadOptions = {
signed?: boolean;
};
type ExpressCookieSetOptions = CookieOptions & {
httpOnly?: boolean;
signed?: boolean;
};Usage:
await cookieStore.set("session", "abc", { signed: true, httpOnly: true });
const session = await cookieStore.get("session", { signed: true });
const allSigned = await cookieStore.getAll({ signed: true });Next Adapter Options
NextCookieStore supports extra options accepted by next/headers cookies API:
type NextCookieOptions = CookieOptions & {
httpOnly?: boolean;
priority?: "low" | "medium" | "high";
};Exports
export { createCookieStore };
export { useCookie, useCookies };
export { CookieProvider };Examples
Runnable examples are included in:
- examples/express
- examples/vite-react-ts
- examples/vite-vanilla-ts
Development
Build
npm run buildWatch Mode
npm run devLint
npm run lintLicense
See LICENSE file for details.
