{"id":13406422,"url":"https://github.com/vvo/iron-session","last_synced_at":"2026-04-02T12:04:14.524Z","repository":{"id":37096891,"uuid":"245132958","full_name":"vvo/iron-session","owner":"vvo","description":"🛠 Secure, stateless, and cookie-based session library for JavaScript","archived":false,"fork":false,"pushed_at":"2025-05-06T23:16:02.000Z","size":8329,"stargazers_count":3917,"open_issues_count":28,"forks_count":254,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-05-07T08:02:03.795Z","etag":null,"topics":["authentication","cookies","expressjs","nextjs","nodejs","serverless","session","stateless"],"latest_commit_sha":null,"homepage":"https://get-iron-session.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vvo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yaml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["vvo","brc-dd"]}},"created_at":"2020-03-05T10:27:50.000Z","updated_at":"2025-05-06T14:49:11.000Z","dependencies_parsed_at":"2023-09-24T09:30:48.373Z","dependency_job_id":"c96b773e-3acb-4695-aacd-fb4de4ba9043","html_url":"https://github.com/vvo/iron-session","commit_stats":{"total_commits":737,"total_committers":49,"mean_commits":"15.040816326530612","dds":0.5101763907734057,"last_synced_commit":"f5ac7e56cfa41cedddacf272614dbd25731a30ac"},"previous_names":["vvo/next-iron-session"],"tags_count":51,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvo%2Firon-session","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvo%2Firon-session/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvo%2Firon-session/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvo%2Firon-session/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vvo","download_url":"https://codeload.github.com/vvo/iron-session/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253908663,"owners_count":21982682,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","cookies","expressjs","nextjs","nodejs","serverless","session","stateless"],"created_at":"2024-07-30T19:02:29.891Z","updated_at":"2026-04-02T12:04:14.511Z","avatar_url":"https://github.com/vvo.png","language":"TypeScript","readme":"# iron-session ![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/vvo/iron-session/ci.yaml) [![GitHub license](https://img.shields.io/github/license/vvo/iron-session?style=flat)](https://github.com/vvo/iron-session/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/iron-session)](https://www.npmjs.com/package/iron-session) ![npm](https://img.shields.io/npm/dm/iron-session) ![npm package minimized gzipped size (select exports)](https://img.shields.io/bundlejs/size/iron-session?exports=getIronSession)\n\n**`iron-session` is a secure, stateless, and cookie-based session library for JavaScript.**\n\n---\n\nThe session data is stored in signed and encrypted cookies which are decoded by your server code in a stateless fashion (= no network involved). This is the same technique used by frameworks like\n[Ruby On Rails](https://guides.rubyonrails.org/security.html#session-storage).\n\n\u003cp align=\"center\"\u003e\u003ci\u003eOnline demo and examples: \u003ca href=\"https://get-iron-session.vercel.app/\"\u003ehttps://get-iron-session.vercel.app\u003c/a\u003e\u003c/i\u003e 👀 \u003cbr/\u003e\n \u003ci\u003eFeatured in the \u003ca href=\"https://nextjs.org/docs/app/guides/authentication\"\u003eNext.js documentation\u003c/a\u003e\u003c/i\u003e ⭐️\u003c/p\u003e\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Examples](#examples)\n- [Project status](#project-status)\n- [Session options](#session-options)\n- [API](#api)\n  - [`getIronSession\u003cT\u003e(req, res, sessionOptions): Promise\u003cIronSession\u003cT\u003e\u003e`](#getironsessiontreq-res-sessionoptions-promiseironsessiont)\n  - [`getIronSession\u003cT\u003e(cookieStore, sessionOptions): Promise\u003cIronSession\u003cT\u003e\u003e`](#getironsessiontcookiestore-sessionoptions-promiseironsessiont)\n  - [`session.save(): Promise\u003cvoid\u003e`](#sessionsave-promisevoid)\n  - [`session.destroy(): void`](#sessiondestroy-void)\n  - [`session.updateConfig(sessionOptions: SessionOptions): void`](#sessionupdateconfigsessionoptions-sessionoptions-void)\n  - [`sealData(data: unknown, { password, ttl }): Promise\u003cstring\u003e`](#sealdatadata-unknown--password-ttl--promisestring)\n  - [`unsealData\u003cT\u003e(seal: string, { password, ttl }): Promise\u003cT\u003e`](#unsealdatatseal-string--password-ttl--promiset)\n- [FAQ](#faq)\n  - [Why use pure cookies for sessions?](#why-use-pure-cookies-for-sessions)\n  - [How to invalidate sessions?](#how-to-invalidate-sessions)\n  - [Can I use something else than cookies?](#can-i-use-something-else-than-cookies)\n  - [How is this different from JWT?](#how-is-this-different-from-jwt)\n- [Credits](#credits)\n- [Good Reads](#good-reads)\n\n## Installation\n\n```sh\npnpm add iron-session\n```\n\n## Usage\n\n*We have extensive examples here too: https://get-iron-session.vercel.app/.*\n\nTo get a session, there's a single method to know: `getIronSession`.\n\n```ts\n// Next.js API Routes and Node.js/Express/Connect.\nimport { getIronSession } from 'iron-session';\n\nexport async function get(req, res) {\n  const session = await getIronSession(req, res, { password: \"...\", cookieName: \"...\" });\n  return session;\n}\n\nexport async function post(req, res) {\n  const session = await getIronSession(req, res, { password: \"...\", cookieName: \"...\" });\n  session.username = \"Alison\";\n  await session.save();\n}\n```\n\n```ts\n// Next.js Route Handlers (App Router)\nimport { cookies } from 'next/headers';\nimport { getIronSession } from 'iron-session';\n\nexport async function GET() {\n  const session = await getIronSession(cookies(), { password: \"...\", cookieName: \"...\" });\n  return session;\n}\n\nexport async function POST() {\n  const session = await getIronSession(cookies(), { password: \"...\", cookieName: \"...\" });\n  session.username = \"Alison\";\n  await session.save();\n}\n```\n\n```tsx\n// Next.js Server Components and Server Actions (App Router)\nimport { cookies } from 'next/headers';\nimport { getIronSession } from 'iron-session';\n\nasync function getIronSessionData() {\n  const session = await getIronSession(cookies(), { password: \"...\", cookieName: \"...\" });\n  return session\n}\n\nasync function Profile() {\n  const session = await getIronSessionData();\n\n  return \u003cdiv\u003e{session.username}\u003c/div\u003e;\n}\n```\n\n## Examples\n\nWe have many different patterns and examples on the online demo, have a look: https://get-iron-session.vercel.app/.\n\n## Project status\n\n✅ Production ready and maintained.\n\n## Session options\n\nTwo options are required: `password` and `cookieName`. Everything else is automatically computed and usually doesn't need to be changed.****\n\n- `password`, **required**: Private key used to encrypt the cookie. It has to be at least 32 characters long. Use \u003chttps://1password.com/password-generator/\u003e to generate strong passwords. `password` can be either a `string` or an `object` with incrementing keys like this: `{2: \"...\", 1: \"...\"}` to allow for password rotation.  iron-session will use the highest numbered key for new cookies.\n- `cookieName`, **required**: Name of the cookie to be stored\n- `ttl`, _optional_: In seconds. Default to the equivalent of 14 days. You can set this to `0` and iron-session will compute the maximum allowed value by cookies.\n- `cookieOptions`, _optional_: Any option available from [jshttp/cookie#serialize](https://github.com/jshttp/cookie#cookieserializename-value-options) except for `encode` which is not a Set-Cookie Attribute. See [Mozilla Set-Cookie Attributes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes) and [Chrome Cookie Fields](https://developer.chrome.com/docs/devtools/application/cookies/#fields). Default to:\n\n  ```js\n  {\n    httpOnly: true,\n    secure: true, // set this to false in local (non-HTTPS) development\n    sameSite: \"lax\",// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#lax\n    maxAge: (ttl === 0 ? 2147483647 : ttl) - 60, // Expire cookie before the session expires.\n    path: \"/\",\n  }\n  ```\n\n## API\n\n### `getIronSession\u003cT\u003e(req, res, sessionOptions): Promise\u003cIronSession\u003cT\u003e\u003e`\n\n```ts\ntype SessionData = {\n  // Your data\n}\n\nconst session = await getIronSession\u003cSessionData\u003e(req, res, sessionOptions);\n```\n\n### `getIronSession\u003cT\u003e(cookieStore, sessionOptions): Promise\u003cIronSession\u003cT\u003e\u003e`\n\n```ts\ntype SessionData = {\n  // Your data\n}\n\nconst session = await getIronSession\u003cSessionData\u003e(cookies(), sessionOptions);\n```\n\n### `session.save(): Promise\u003cvoid\u003e`\n\nSaves the session. This is an asynchronous operation. It must be done and awaited before headers are sent to the client.\n\n```ts\nawait session.save()\n```\n\n### `session.destroy(): void`\n\nDestroys the session. This is a synchronous operation as it only removes the cookie. It must be done before headers are sent to the client.\n\n```ts\nsession.destroy()\n```\n\n### `session.updateConfig(sessionOptions: SessionOptions): void`\n\nUpdates the configuration of the session with new session options. You still need to call save() if you want them to be applied.\n\n### `sealData(data: unknown, { password, ttl }): Promise\u003cstring\u003e`\n\nThis is the underlying method and seal mechanism that powers `iron-session`. You can use it to seal any `data` you want and pass it around. One usecase are magic links: you generate a seal that contains a user id to login and send it to a route on your website (like `/magic-login`). Once received, you can safely decode the seal with `unsealData` and log the user in.\n\n### `unsealData\u003cT\u003e(seal: string, { password, ttl }): Promise\u003cT\u003e`\n\nThis is the opposite of `sealData` and allow you to decode a seal to get the original data back.\n\n## FAQ\n\n### Why use pure cookies for sessions?\n\nThis makes your sessions stateless: since the data is passed around in cookies, you do not need any server or service to store session data.\n\nMore information can also be found on the [Ruby On Rails website](https://guides.rubyonrails.org/security.html#session-storage) which uses the same technique.\n\n### How to invalidate sessions?\n\nSessions cannot be instantly invalidated (or \"disconnect this customer\") as there is typically no state stored about sessions on the server by default. However, in most applications, the first step upon receiving an authenticated request is to validate the user and their permissions in the database. So, to easily disconnect customers (or invalidate sessions), you can add an `isBlocked`` state in the database and create a UI to block customers.\n\nThen, every time a request is received that involves reading or altering sensitive data, make sure to check this flag.\n\n### Can I use something else than cookies?\n\nYes, we expose `sealData` and `unsealData` which are not tied to cookies. This way you can seal and unseal any object in your application and move seals around to login users.\n\n### How is this different from [JWT](https://jwt.io/)?\n\nNot so much:\n\n- JWT is a standard, it stores metadata in the JWT token themselves to ensure communication between different systems is flawless.\n- JWT tokens are not encrypted, the payload is visible by customers if they manage to inspect the seal. You would have to use [JWE](https://tools.ietf.org/html/rfc7516) to achieve the same.\n- @hapi/iron mechanism is not a standard, it's a way to sign and encrypt data into seals\n\nDepending on your own needs and preferences, `iron-session` may or may not fit you.\n\n## Credits\n\n- [Eran Hammer and hapi.js contributors](https://github.com/hapijs/iron/graphs/contributors)\n  for creating the underlying cryptography library\n  [`@hapi/iron`](https://hapi.dev/module/iron/).\n- [Divyansh Singh](https://github.com/brc-dd) for reimplementing `@hapi/iron` as\n  [`iron-webcrypto`](https://github.com/brc-dd/iron-webcrypto) using standard\n  web APIs.\n- [Hoang Vo](https://github.com/hoangvvo) for advice and guidance while building\n  this module. Hoang built\n  [`next-connect`](https://github.com/hoangvvo/next-connect) and\n  [`next-session`](https://github.com/hoangvvo/next-session).\n- All the\n  [contributors](https://github.com/vvo/iron-session/graphs/contributors) for\n  making this project better.\n\n## Good Reads\n\n- \u003chttps://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html\u003e\n- \u003chttps://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html\u003e\n","funding_links":["https://github.com/sponsors/vvo","https://github.com/sponsors/brc-dd"],"categories":["Miscellaneous","miscellaneous","TypeScript","Auth / Authz"],"sub_categories":["Miscellaneous"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvvo%2Firon-session","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvvo%2Firon-session","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvvo%2Firon-session/lists"}