Library / SDK
js-cookie/js-cookie avatar
js-cookie/js-cookie

js-cookie: a small client-side cookie API, and where it stops

A simple, lightweight JavaScript API for handling cookies, client-side.

22,585 stars2,042 forksJavaScriptMIT

At a glance

What is it?
js-cookie wraps document.cookie in set, get and remove calls and ships under 800 bytes gzipped. It is a good fit for plain browser code and a poor fit for server-side rendering, where it has no access to the response headers.
Who is it for?
Adopt js-cookie for client-side code that needs readable cookie handling without a framework dependency, and skip it if your cookies must be set during server rendering, because the README states the library is client-side only and the repository ships a separate SERVER_SIDE.md file for that case.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What js-cookie replaces, and who ends up using it

The browser gives you one primitive for cookies: the document.cookie string. Reading it means splitting on semicolons and trimming; writing it means concatenating a name, a value and a list of attributes in the exact order the specification expects. js-cookie turns that into three functions. Cookies.set('name', 'value') writes, Cookies.get('name') reads back 'value', and Cookies.remove('name') deletes. The README describes the library as "a simple, lightweight JavaScript API for handling cookies, client-side" and lists its selling points as no dependency, support for both ES and AMD/CommonJS modules, and RFC 6265 compliance.

The audience is narrow and predictable. Front-end code that needs to remember a UI preference, a locale, or a token it received from an API. Widgets and SDKs embedded on third-party sites, which is why the library keeps a noConflict method that reassigns the API to a new variable and restores the original window.Cookies. Teams that would otherwise write their own cookie parser and get the percent-encoding wrong. If your cookies are set by a server framework and only read in the browser, js-cookie covers the read half and nothing else.

How set, get and remove map onto the cookie string

There is no hidden state. Each call builds or parses a string and hands it to the document. That is the whole architecture, and it explains both the size and the limitations.

Attributes are passed as a plain object in the last argument. expires accepts a Number, interpreted as days from creation, or a Date instance. If you omit it, the cookie becomes a session cookie and disappears when the browser closes. path defaults to '/', so a cookie written without options is valid across the entire site. Per-call attributes override defaults set globally through withAttributes().

Removal is where the design bites. Cookies.remove('name') matches on name plus the default attributes, so a cookie written with { path: '' } will not be removed by a bare remove call. The README is explicit about this: "When deleting a cookie and you're not relying on the default attributes, you must pass the exact same path, domain, secure and sameSite attributes that were used to set the cookie." The same rule applies to reading. Passing { domain: 'sub.example.com' } to Cookies.get has no effect, because visibility is decided by the browser before your code sees anything.

Encoding is the other mechanism worth knowing. Special characters in names and values are percent-encoded using their UTF-8 hex equivalents, and the percent character itself is escaped so literal input round-trips. The README warns that this default strategy is "meant to be interoperable only between cookies that are read/written by js-cookie." A cookie written by js-cookie and read by a server-side language with a different decoder can come back wrong. Converters exist to change that behaviour, but you have to configure them on both ends.

Installing js-cookie and reading a cookie back in the browser

The npm package is the normal path. Run the install command from the README:

bash
npm i js-cookie

The package has a module field pointing at an ES module variant and a browser field pointing at a UMD build. Since not all browsers support ES modules natively, the README suggests shipping the ES module with the UMD fallback. If you prefer not to bundle, jsDelivr serves the package directly.

Once installed, import the default export and write a cookie that expires in seven days:

javascript
import Cookies from 'js-cookie'

Cookies.set('name', 'value', { expires: 7 })
Cookies.get('name') // => 'value'

The get call returns the string 'value'. A name that was never written returns undefined, not an empty string, so truthiness checks work. Calling Cookies.get() with no argument returns an object of every cookie visible to the current page.

Deletion needs the attributes to match. If you wrote the cookie with an empty path, remove it the same way:

javascript
Cookies.set('name', 'value', { path: '' })
Cookies.remove('name') // fail!
Cookies.remove('name', { path: '' }) // removed!

The README shows exactly this pair, and it is the single most common mistake with the library. Removing a cookie that does not exist raises no exception and returns no value, so a failed removal is silent.

The client-side boundary is the real limitation

js-cookie runs in the browser and only in the browser. There is no server-side API, which means it cannot participate in server rendering. If your framework renders a page on the server and you call Cookies.set during that render, there is no document to write to. The repository acknowledges this by shipping a SERVER_SIDE.md file alongside the README, and the npm keywords list "client" as a category. That file is the pointer to whatever the project recommends for the server case, and it is the first thing to read before planning an SSR integration.

A second boundary is the absence of cryptographic protection. The library writes and reads; it does not sign, encrypt or validate. A cookie set with js-cookie is readable and editable by anyone with the browser console. The README does not claim otherwise, and no part of the API suggests integrity checking. If a value must survive tampering, js-cookie is the wrong layer.

Third, the default encoding is not a wire format. Because percent-encoding is applied in a way designed for js-cookie to read back its own output, interop with other cookie producers requires converters. Teams that mix a server-set cookie with a client-set cookie of the same name should decide on one encoder rather than assume the defaults agree.

Finally, size limits are the browser's, not the library's. The README points at RFC 6265 section 6.1 and notes that cookies may be deleted if they are too big or if too many exist on the same domain, linking to a wiki FAQ for details.

js-cookie against document.cookie and against local storage

The most direct alternative is document.cookie itself. Parsing it by hand costs nothing in bundle size and gives you full control over the encoder. The trade-off is that you own the percent-encoding, the attribute ordering and the removal-matching logic, and those are precisely the places where hand-rolled cookie code breaks. js-cookie is under 800 bytes gzipped according to the README, so the size argument for going manual is weak unless you need a custom codec anyway.

The other comparison people raise is local storage. The two solve different problems. Local storage is not sent with HTTP requests, so a value stored there never reaches your server. Cookies are sent automatically with every matching request, which is why session identifiers live in cookies and UI state usually does not. js-cookie has no opinion on this; it is a cookie library, and using it to store data that never needs to travel to the server adds bytes to every request for no benefit.

Framework-specific cookie packages exist for React and similar environments, and they typically add hooks or context integration on top of the same document.cookie primitive. If you are already inside a framework with its own cookie helpers, adding js-cookie means two cookie APIs in the same bundle. Pick one. js-cookie earns its place when the code is framework-agnostic, or when the same cookie handling has to work in a widget, a plain script tag and a bundled module.

Maintenance, releases and what the MIT licence lets you do

The repository is not archived, and the last push was on 2026-09-17. Releases are not on a fixed cadence: v3.0.5 landed in April 2023, v3.0.7 in May 2026, v3.0.8 on 2026-05-29. A three-year gap between v3.0.5 and v3.0.7 is visible in the release list, so anyone pinning a version should read the changelog for that span rather than assume incremental patches. The package version in package.json is 3.0.8, matching the latest release.

The build is Rollup with terser, tests run through Grunt and QUnit, and there is a separate browserstack script for cross-browser runs. That toolchain is heavier than the library itself, which matters only if you intend to fork and rebuild.

The licence is MIT. In practical terms that permits commercial use, modification and redistribution provided the copyright notice and permission notice are included. This is not legal advice, and if you are redistributing the library inside a product, the LICENSE file is the document to read. There is no dual-licensing scheme and no commercial tier mentioned in the README.

Upgrade cost is low by design. The public surface is set, get, remove, withAttributes, noConflict and the converter hooks. A major version bump would be the only thing likely to touch that surface, and the 3.x line has stayed on it.

Editorial conclusion

Adopt js-cookie for client-side code that needs readable cookie handling without a framework dependency, and skip it if your cookies must be set during server rendering, because the README states the library is client-side only and the repository ships a separate SERVER_SIDE.md file for that case. Before committing, check that your build resolves the exports map correctly: the import condition points at dist/js.cookie.mjs and the require condition at dist/js.cookie.js, and bundlers that ignore exports may pick the browser field instead.

Frequently asked questions

How do I install js-cookie?

Run npm i js-cookie, then import the default export with import Cookies from 'js-cookie' or require it with const Cookies = require('js-cookie'). If you do not want to bundle it, the README points to the jsDelivr CDN as an alternative.

How do I use js-cookie in React?

The README does not document React integration, and the library has no hooks or context of its own. It is a plain module, so you call Cookies.set, Cookies.get and Cookies.remove from wherever your React code runs in the browser, and the same client-side constraint applies.

What is js-cookie?

It is a client-side JavaScript API for handling cookies, described in the README as simple and lightweight, with no dependencies and RFC 6265 compliance. It exposes set, get and remove instead of requiring you to build and parse the document.cookie string yourself.

Is js-cookie secure?

The library only writes and reads cookie values; it does not sign, encrypt or validate them, and the README makes no security claim. The secure and sameSite attributes are passed through when you set a cookie, so the transport-level protections come from those attributes and from the browser, not from js-cookie itself.

What is the difference between js-cookie and local storage?

js-cookie manages cookies, which the browser sends with matching HTTP requests, while local storage stays in the browser and is never transmitted. The README does not compare the two, so the choice depends on whether the value needs to reach your server on each request.

How do I use js-cookie?

Import the default export, then call Cookies.set('name', 'value') to write, Cookies.get('name') to read back the string, and Cookies.remove('name') to delete. Attributes such as expires and path are passed as an object in the last argument.

Official sources

  1. Issues
  2. js-cookie/js-cookie on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/js-cookie-js-cookie.svg)](https://hysenlabs.com/projects/js-cookie-js-cookie)