If you’ve ever wrangled document.cookie, you know it’s a synchronous string mess that’s easy to misuse and hard to reason about. The Cookie Store API modernizes cookies with a promise-based, structured interface that works in window and service worker contexts. It enables async reads/writes, typed cookie objects, and change events—perfect for performance-sensitive and offline-capable apps.
What it looks like
Set a cookie asynchronously
cookieStore.set({ name, value, expires, path, sameSite });
Returns a promise; no string parsing needed.
Read a cookie
cookieStore.get(name);
Resolves to a cookie object or null.
List cookies
cookieStore.getAll();
Returns an array of cookie objects.
Delete a cookie
cookieStore.delete(name);
Removes it by key.
Listen for changes
cookieStore.addEventListener('change', handler);
Fires when cookies are changed or deleted—even across tabs (where supported).
Walking through the demo
- setCookie creates demoCookie with a value of cookieStoreRocks that expires in one hour, scoped to / with SameSite=lax by default.
- getCookie retrieves it and logs its value.
- listCookies inspects all cookies available to the current scope.
- deleteCookie removes demoCookie.
- The change event listener logs both “changed” and “deleted” cookies, so you can react to login/logout or preference updates in real time.
// 1. Set a cookie asynchronously
const setCookie = async () => {
await cookieStore.set({
name: 'demoCookie',
value: 'cookieStoreRocks',
expires: Date.now() + 60 * 60 * 1000, // 1 hour from now
path: '/',
sameSite: 'lax'
});
console.log('Cookie set!');
};
// 2. Get a cookie by name
const getCookie = async () => {
const cookie = await cookieStore.get('demoCookie');
if (cookie) {
console.log('Cookie value:', cookie.value);
} else {
console.log('Cookie not found.');
}
};
// 3. List all cookies
const listCookies = async () => {
const cookies = await cookieStore.getAll();
console.log('All cookies:', cookies);
};
// 4. Delete a cookie
const deleteCookie = async () => {
await cookieStore.delete('demoCookie');
console.log('Cookie deleted!');
};
// 5. Listen for cookie changes (works in supported browsers)
cookieStore.addEventListener('change', (event) => {
for (const changed of event.changed) {
console.log('Cookie changed:', changed);
}
for (const deleted of event.deleted) {
console.log('Cookie deleted:', deleted);
}
});
// --- Demo sequence ---
(async () => {
await setCookie();
await getCookie();
await listCookies();
await deleteCookie();
await listCookies();
})();
Why it’s better
- Async and structured: No blocking the main thread; you get real objects, not a semicolon soup.
- Works in service workers: Useful for background sync or auth state reflection.
- Event-driven: Keep UI and state in sync when cookies change elsewhere.
Practical tips and caveats
- Browser support: Still evolving. Feature-detect with if ('cookieStore' in self) before using, and provide fallbacks to document.cookie when needed.
- Security attributes: Use Secure and SameSite appropriately. For cross-site use-cases, explicitly set sameSite: 'none' and ensure Secure in HTTPS contexts.
- HttpOnly cookies: You cannot read or write HttpOnly cookies from JavaScript (by design). Server must manage those.
- Path/domain scope: Reads and writes are constrained by path and domain rules, just like traditional cookies.
- Storage limits: Cookies are size- and count-limited; don’t treat them like a database.
Getting started snippet
- The provided code shows the full flow: set → get → list → delete, plus change events.
- Wrap calls in try/catch for production, and guard with feature detection.
Example feature detection
if (!('cookieStore' in self)) {
console.warn('Cookie Store API not supported; falling back to document.cookie.');
// Provide polyfill or minimal fallback here.
}
Bottom line
The Cookie Store API brings cookies into the modern web platform: async, typed, and event-driven. Use it to simplify auth state, user preferences, and multi-tab coordination—just remember to feature-detect and keep security attributes tight.

