nookies: cookie helpers that span Next.js server, client and Express
🍪 A set of cookie helpers for Next.js
At a glance
- What is it?
- A small TypeScript library with three cookie functions and two calling conventions, shipped as a yarn workspaces monorepo. The MIT claim in its README and its missing license metadata are worth reconciling before you ship it.
- Who is it for?
- nookies is small on purpose and the API surface reflects that decision: three functions, each with a default-export alias, each accepting either a Next.js context or a bare request or response object. What you get over writing it yourself is one implementation of cookie encoding, decoding and expiry that behaves the same in `getServerSideProps`, in a click handler and in a custom Express route, which is exactly the class of bug that is annoying to chase.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 20 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 8, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the library actually does
The README describes nookies as a collection of cookie helpers for Next.js, and the description on the repository puts a cookie emoji in front of the same sentence. Four features are listed, and they are the whole pitch: server-side rendering support for the setter, the parser and the destroy function; custom Express server support; a small footprint; and suitability for authentication.
The implementation matches that description closely. There are three functions, each available under two names. `parseCookies(ctx, options)` is also `nookies.get(ctx, options)`. `setCookie(ctx, name, value, options)` is also `nookies.set(...)`. `destroyCookie(ctx, name, options)` is also `nookies.destroy(...)`. There is no plugin system, no cookie signing, no encryption and no schema. Everything else is the standard cookie options list, passed through.
Install is `yarn add nookies`, and the README links a CodeSandbox for trying it without setting anything up. The repository sits at 2,352 stars and 75 forks, is written in TypeScript, carries the topics cookie, hacktoberfest, nextjs, react and zeit, was last pushed on 2026-09-18, and is not archived.
The server-side shape inside getServerSideProps
The primary example is a Next.js page module that parses, sets and optionally destroys cookies in `getServerSideProps`:
import nookies from 'nookies'
export async function getServerSideProps(ctx) {
const cookies = nookies.get(ctx)
nookies.set(ctx, 'fromGetInitialProps', 'value', {
maxAge: 30 * 24 * 60 * 60,
path: '/',
})
return { cookies }
}Three details in that snippet carry most of the library's usefulness. Setting a cookie works during server-side rendering, which means the first response already carries the header rather than the cookie appearing after hydration. The options object is the standard shape, and `maxAge: 30 * 24 * 60 * 60` is thirty days in seconds written out longhand. And the parsed cookies are returned as page props, so the same request that reads the cookie can hand it to the component tree.
The default import is what makes this read cleanly. `nookies.get` and `nookies.set` are the same functions as the named exports, so the choice between them is a style decision rather than an API decision. The README consistently shows the default-import form for server code and the named form for client code.
Client-side calls omit the context argument entirely
On the client there is no Next.js context, so the argument goes away. The README's client example imports the named functions and passes `null`:
import { parseCookies, setCookie, destroyCookie } from 'nookies'
function handleClick() {
const cookies = parseCookies()
setCookie(null, 'fromClient', 'value', {
maxAge: 30 * 24 * 60 * 60,
path: '/',
})
}The Reference section spells out the rule precisely: for client-side usage, omit the `ctx` parameter, and you can do so by setting it to an empty object `{}`, `null` or `undefined`. So a call site that still receives a possibly-absent context works unchanged on both sides, which is the practical reason the parameter is not removed rather than optional in the type signature.
This is also the part of the design most worth reading carefully, because it is where a cookie helper can quietly go wrong. On the client, a cookie set without `path` will not be visible to pages outside the current directory, and the README lists `path` among the supported options for exactly that reason. The default `encode` and `decode` behaviour is also worth noting: `parseCookies` takes a `decode` option described as a custom resolver function defaulting to `decodeURIComponent`.
Custom Express servers pass req and res instead
The third example covers the case the feature list calls custom Express server support. Here the arguments are not a context object but the pieces you need individually, and the comments in the example say which is which:
const { parseCookies, setCookie, destroyCookie } = require('nookies');
server.get('/page', (req, res) => {
const parsedCookies = parseCookies({ req });
setCookie({ res }, 'fromServer', 'value', {
maxAge: 30 * 24 * 60 * 60,
path: '/page',
});
});So the three functions accept `{ req }` to read and `{ res }` to write, and `destroyCookie` also wants `{ res }`. The Reference section states the same thing in its parameter lists: `ctx` is a Next.js context or an Express request object, and for `destroyCookie` it is a Next.js context or an Express response object.
Two warnings in the Reference section are worth repeating because they are the common failure. It says not to forget to end your server response with `res.send()`, and for `destroyCookie` it adds that this might be the reason your cookie is not removed. A cookie header written but never flushed with the response simply does not reach the client, and that symptom looks exactly like a library bug.
A monorepo, two workspaces, and where the code lives
The repository is a yarn workspaces monorepo. The root `package.json` is named `workspace`, is marked private, and declares two workspace globs: `packages/*` and `examples/*`. Its scripts are thin wrappers that jump to the calling directory, with `g:tsc` running `tsc` in `$INIT_CWD` and `g:prettier` doing the same for prettier, and the devDependencies pin husky, prettier, pretty-quick, rimraf and TypeScript at 4.7.4.
That layout tells you something about the project's shape. The library lives under `packages/`, so the actual source is not at the repository root, and the `examples/*` workspace means the examples are installed and type-checked alongside it rather than being documentation snippets that can drift. The rest of the tree supports that workflow: `.huskyrc.json` for git hooks, `.yarn/` and `.yarnrc.yml` for the yarn release and configuration, `prettier.config.js`, `renovate.json`, `tsconfig.json`, `CONTRIBUTING.md` and `yarn.lock`. Husky and pretty-quick together are what make formatting checks run before a commit lands.
The release history is conventional semantic versioning with conventional-commit messages. v2.5.2 on 2021-01-21 was a bug fix for optional options in the `setCookie` function, v2.5.1 on 2021-01-16 fixed multiple complex cookies and closes issue #401, and v2.5.0 on 2020-10-31 bumped dependencies. With 32 open issues at 2,352 stars, the ratio of open issues to popularity is higher than for a typical utility, which is worth factoring into any adoption decision.
The license question, stated plainly
The repository's license metadata is empty. The README's License section says MIT, in full, on its own line at the bottom of the page. Those two facts are both true in the data and neither cancels the other, so here is what a reader can act on.
The README claim is the more specific of the two, and MIT is the licence a small helper library almost always intends. But an empty license field is the thing GitHub uses to decide whether to show a licence badge, and it is also what automated tooling reads. If you are choosing between those two facts, use this test: check whether a `LICENSE` file exists at the repository root. The repository tree lists `README.md`, `package.json`, `tsconfig.json`, `CONTRIBUTING.md` and the workspace directories, and it does not list a top-level `LICENSE` file. If that holds, then the grant exists only as a README sentence rather than as the licence text MIT requires, and for internal use that is almost always fine while for redistribution it is the thing to raise with the maintainer.
There is a second currency signal next to it. The last release is v2.5.2 from 2021-01-21, which is the last documented change to the API, with the `setCookie` options becoming optional. The repository was pushed on 2026-09-18 and is not archived, so commits continue, but there has been no tagged release in years. For a library this small that is not necessarily a problem, since the entire public surface is three functions documented in the README, but it does mean the npm version you install is old and you should read the Reference section rather than trusting a version number.
Editorial conclusion
nookies is small on purpose and the API surface reflects that decision: three functions, each with a default-export alias, each accepting either a Next.js context or a bare request or response object. What you get over writing it yourself is one implementation of cookie encoding, decoding and expiry that behaves the same in `getServerSideProps`, in a click handler and in a custom Express route, which is exactly the class of bug that is annoying to chase. The two things to check before adopting it are licensing, because the repository's license field is empty while the README ends with MIT, and currency, because the last release is v2.5.2 from January 2021 even though the repository was pushed on 2026-09-18. Read the license question against the actual LICENSE situation, install from npm rather than from git, and read the Reference section of the README before wiring cookies into an auth flow.
Frequently asked questions
What does nookies mean in slang?
Nothing in this library's case. nookies is the package name of a set of cookie helpers for Next.js by maticzav, described in its README as a collection of cookie helpers for Next.js with SSR, client and custom Express support. Slang uses of the word and the Chicago sandwich chain named Nookies are unrelated.
What are the three functions nookies exports?
`parseCookies(ctx, options)`, also available as `nookies.get(ctx, options)`; `setCookie(ctx, name, value, options)`, also `nookies.set(...)`; and `destroyCookie(ctx, name, options)`, also `nookies.destroy(...)`. On the client you omit the ctx argument, passing `{}`, `null` or `undefined`.
Why is my cookie not being removed by destroyCookie?
The README singles this out twice: do not forget to end your server response with `res.send()`, and notes that this might be the reason your cookie is not removed. `destroyCookie` needs the response object, `{ res }` on Express or the context on Next.js, and the header is not sent until the response is finished.
Which cookie options does nookies support?
`setCookie` takes domain, encode, expires, httpOnly, maxAge, path, sameSite and secure. `destroyCookie` takes a shorter list of domain and path. `parseCookies` takes a `decode` option, a custom resolver function that defaults to `decodeURIComponent`.
Official sources
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.
[](https://hysenlabs.com/projects/maticzav-nookies)