5 min read
I bundled the two Cookie-header helpers on this box: cookie-es 3.1.1 came out at 2,295 bytes gzip for the full export set, while jshttp cookie 2.0.1 came out at 1,446 bytes. Cookie-header parse matched on my fixtures. Set-Cookie parse favored cookie (~1.2 µs vs ~2.0 µs per three-header pass).
Short answer: pick cookie when you want the smaller modern API (object stringify + Set-Cookie helpers). Keep cookie-es when you still call serialize(name, value, options) the Express way, or when you need splitSetCookieString. No affiliate links in this post.
| Build (esbuild minify, gzip -9) | Minified | gzip |
|---|---|---|
| cookie-es full exports | 6,044 B | 2,295 B |
| cookie full exports | 3,663 B | 1,446 B |
| cookie-es parseCookie only | 901 B | 512 B |
| cookie parseCookie only | 753 B | 420 B |
cookie wins size on both the full API and the parse-only cut. Track the delta the same way as size-limit vs bundlesize. Other unjs vs stdlib swaps in this series include pathe vs node:path and klona vs structuredClone.
| Check | cookie-es 3.1.1 | cookie 2.0.1 |
|---|---|---|
| parseCookie on mixed header | same object keys/values | same |
| parseSetCookie Max-Age / SameSite | same fields | same |
| stringify multi Cookie object | session=abc; theme=dark | session=abc; theme=dark |
| serialize(name, value, opts) | yes (classic) | no — use stringifySetCookie |
| splitSetCookieString | yes | no |
Header parse matched byte-for-byte on my fixture (including a percent-decoded space). The API shape is the real decision. cookie-es keeps Express-era serialize; cookie 2.x wants objects. If your stack already leans unjs for HTTP clients, compare ky vs axios. Request mocking sits next door in msw vs nock.
| Cost (200k outer iters, median of 9, 2 runs) | cookie-es | cookie |
|---|---|---|
| parseCookie (5 headers), µs / outer | 1.65 / 1.60 | 1.67 / 1.62 |
| parseSetCookie (3 headers), µs / outer | 2.04 / 1.98 | 1.20 / 1.17 |
| serialize name/value or stringify one key, ns | ~241 / 220 (serialize) | ~93 / 101 (stringify obj) |
Cookie-header parse is a wash. Set-Cookie parse and simple stringify favored cookie on this box. For edge middleware that only reads Cookie headers, size and API matter more than the nanoseconds. Schema validation at the boundary is a different tool; see zod vs valibot and ajv vs zod.
| Situation | My pick |
|---|---|
| New code, want smaller bundle | cookie 2.x |
| Need stringifySetCookie / parseSetCookie only | cookie 2.x |
| Existing serialize(name, value, options) call sites | cookie-es |
| Need splitSetCookieString for combined Set-Cookie | cookie-es |
| Migrating from cookie 1.x serialize without rewriting | cookie-es first, or rewrite to objects |
Bottom line: cookie 2.0.1 was 1,446 B gzip versus 2,295 B for cookie-es 3.1.1, with matching Cookie-header parse and faster Set-Cookie parse on this box. Who should not switch yet: codebases with hundreds of serialize(name, value) call sites and no time to move to object stringify. Config and merge helpers nearby include defu vs lodash.merge.
How this was made: I installed both packages on the ShopperCove box, measured esbuild bundles, timed parse/serialize/Set-Cookie loops in two order-reversed runs, and compared parse outputs on shared fixtures. The JSON results sit next to the scripts. The write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 6 Oct 2026 ~01:55 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). cookie-es 3.1.1 vs cookie 2.0.1, esbuild 0.28.2 minify + gzip -9. Size: cookie-es full 6,044/2,295 B vs cookie 3,663/1,446 B; parse-only 901/512 vs 753/420. Speed (200,000 outer iters, 9-round median, order-reversed): parseCookie 5-header pass ces 1,649.7 / 1,604.6 ns vs cookie 1,673.5 / 1,624.8 ns; parseSetCookie 3-header ces 2,037.9 / 1,983.2 vs cookie 1,196.5 / 1,174.0; ces serialize name/value 241.1 / 220.0 ns vs cookie stringify one-key 92.9 / 100.5 ns. Behavior: parseCookie values matched; cookie 2.x stringifyCookie is object-only; cookie-es retains serialize(name,value,opts) and splitSetCookieString. Not tested: browsers, signed cookies, tough-cookie jars, HTTP/2 trailers. No affiliate.