npm.io
0.1.1 • Published 6d ago

@billdaddy/cookiekit

Licence
MIT
Version
0.1.1
Deps
0
Size
35 kB
Vulns
0
Weekly
42

cookiekit

All Contributors

Tiny, type-safe HTTP cookie parse & serialize — RFC 6265 with SameSite, Partitioned, and Priority. Zero dependencies.

CI npm version bundle size types license

Reading a Cookie header and building a Set-Cookie is the kind of thing you should never hand-roll — the encoding and attribute rules are fiddly and a mistake is a security bug. cookiekit does both per RFC 6265, validates names and values, and supports the modern attributes (SameSite, Partitioned, Priority). Zero dependencies, isomorphic.

import { parse, serialize } from "@billdaddy/cookiekit";

parse("sid=abc; theme=dark");
// { sid: "abc", theme: "dark" }

serialize("sid", "abc", { httpOnly: true, secure: true, sameSite: "lax", maxAge: 3600 });
// "sid=abc; Max-Age=3600; HttpOnly; Secure; SameSite=Lax"

Why cookiekit?

  • Both directions, done right. parse decodes and de-quotes; serialize encodes and validates the name, value, domain, and path.
  • Modern attributes. SameSite (lax/strict/none), Partitioned (CHIPS), and Priority — alongside Max-Age, Expires, Domain, Path, HttpOnly, Secure.
  • Safe by default. Throws TypeError on an invalid name/value/domain/path instead of emitting a broken header.
  • Isomorphic & tiny. Works in Node, Deno, Bun, the edge, and browsers. Full types, ESM + CJS, zero dependencies.

Install

npm install @billdaddy/cookiekit
# or: pnpm add @billdaddy/cookiekit  /  yarn add @billdaddy/cookiekit  /  bun add @billdaddy/cookiekit

parse(header, options?)

import { parse } from "@billdaddy/cookiekit";

parse("a=1; b=hello%20world");  // { a: "1", b: "hello world" }
parse('id="42"; theme=dark');   // { id: "42", theme: "dark" }
parse("a=1; a=2");              // { a: "1" }  (first wins)

// custom decoder
parse("a=AAA", { decode: (v) => v.toLowerCase() }); // { a: "aaa" }

Whitespace is trimmed, a single layer of quotes is stripped, and values are decoded (default decodeURIComponent, which falls back to the raw string on malformed input).

serialize(name, value, options?)

import { serialize } from "@billdaddy/cookiekit";

serialize("sid", "abc", {
  maxAge: 60 * 60,        // Max-Age (integer seconds)
  expires: new Date(),    // Expires
  domain: "example.com",
  path: "/",
  httpOnly: true,
  secure: true,
  sameSite: "lax",        // "lax" | "strict" | "none" | true (= Strict)
  partitioned: true,      // CHIPS
  priority: "high",       // "low" | "medium" | "high"
});
interface SerializeOptions {
  encode?: (value: string) => string; // default encodeURIComponent
  maxAge?: number;        // integer seconds
  expires?: Date;
  domain?: string;
  path?: string;
  httpOnly?: boolean;
  secure?: boolean;
  partitioned?: boolean;
  priority?: "low" | "medium" | "high";
  sameSite?: "lax" | "strict" | "none" | boolean;
}

Invalid input throws TypeError — e.g. a name with spaces, a non-integer maxAge, an invalid domain/path, or a value that doesn't survive encoding.

Pairs well with

Need Use
Parse/stringify URL query strings @billdaddy/qskit
Base64URL encode a signed cookie payload codeckit

Contributors

This project follows the all-contributors specification. Contributions of any kind are welcome — code, docs, bug reports, ideas, reviews! See the emoji key for how each contribution is recognized, and open a PR or issue to get involved.

Thanks goes to these wonderful people:

Tung Tran
Tung Tran

License

MIT Tung Tran

Keywords