express-session
Simple, pluggable session middleware for Express that signs session IDs into a cookie and delegates data storage to any compatible store.
Repository Health
Technical Analysis
express-session is the standard session middleware for Express applications, attaching req.session to every request, signing the session ID into an HttpOnly cookie, and persisting the actual session data through a pluggable Store interface rather than in the cookie itself. It ships with an in-memory MemoryStore intended only for local development, and defers real persistence to any of dozens of community-maintained stores backed by Redis, MongoDB, PostgreSQL, and other databases.
Maintained by the Express core team, it exposes fine-grained cookie controls (domain, path, expires/maxAge, sameSite, secure, partitioned, priority) including ‘auto’ resolution for secure and sameSite behind reverse proxies, plus resave/rolling/saveUninitialized flags that let applications tune exactly when sessions get written back to the store.
What You Get
- Drop-in Express middleware - a single session() call attaches req.session, req.sessionID, and req.sessionStore to every request.
- Pluggable Store interface - session/store.js defines a minimal get/set/destroy (plus optional touch) contract implemented by dozens of third-party stores.
- Fine-grained cookie configuration - control domain, path, expires/maxAge, sameSite, secure, partitioned, and priority attributes, including a callback form for per-request cookie options.
- Signed session IDs - session IDs are HMAC-signed via cookie-signature with support for secret rotation using an array of secrets.
- Built-in MemoryStore - a bundled non-production store for local development and quick prototyping.
Common Use Cases
- Server-rendered login sessions - track an authenticated user via req.session.user across requests without a separate auth token.
- Per-visitor state in traditional web apps - store shopping-cart contents, view counters, or multi-step form progress server-side.
- Reverse-proxy deployments - use cookie.secure/sameSite ‘auto’ plus Express’s trust proxy setting to correctly mark cookies as secure behind a load balancer.
- Multi-instance deployments backed by shared stores - swap MemoryStore for connect-redis/connect-mongo/connect-pg-simple to share sessions across horizontally scaled processes.
Under The Hood
Architecture index.js (741 lines) exports a single session() factory that closes over per-instance config (secret, store, cookie options, resave/rolling/saveUninitialized flags) and returns Express middleware; the middleware wraps res.end/res.write to guarantee the session is saved, touched, or destroyed exactly once before the response completes, and uses the on-headers package to inject Set-Cookie just before headers flush. Persistence is delegated to session/store.js: Store extends Node’s EventEmitter and provides regenerate/load/createSession helpers built on required prototype methods (get/set/destroy) that concrete stores must implement — this is the plug-point that the wider session-store ecosystem (connect-redis, connect-mongo, and dozens more) hooks into. session/session.js defines the Session constructor attached to req.session with save/reload/destroy/touch delegating back to req.sessionStore, and session/cookie.js wraps cookie serialization and expiry math in a Cookie class exposed on req.session.cookie. The layout is flat and clearly separated (entry/store/session/cookie) rather than deeply layered; the abstraction most external code depends on, and that would break the most on change, is the Store method contract.
Tech Stack A plain Node.js CommonJS module (no TypeScript, no build step) targeting Node >= 0.8.0. Runtime dependencies are minimal and pinned with tilde ranges: cookie for Set-Cookie parsing/serialization, cookie-signature for HMAC-signed session IDs, debug for namespaced logging, depd for deprecation warnings, on-headers to hook the response header flush, parseurl for cheap URL parsing, safe-buffer for older-Node Buffer compatibility, and uid-safe for cryptographically random session ID generation. Dev tooling is Mocha plus nyc for coverage, supertest and cookie-parser for integration-style HTTP tests, and ESLint (with a markdown plugin that lints the README’s code fences) for style. CI runs via GitHub Actions alongside dedicated CodeQL and OpenSSF Scorecard workflows for supply-chain scanning. No database or ORM ships with the package — all persistence is delegated to third-party Store implementations.
Code Quality test/session.js is a single large Mocha suite (65 describe blocks, roughly 160 individual tests) covering nearly every option combination — resave, rolling, saveUninitialized, unset, proxy, secure/sameSite ‘auto’, dynamic cookie functions, and RFC 6265 path matching — alongside a dedicated test/cookie.js for Cookie-class behavior; supertest drives real HTTP requests against Express apps assembled in test/support, with nyc producing coverage for the project’s Coveralls badge. Error handling is explicit and defensive: options are validated with thrown TypeErrors during setup (genid must be a function, unset must be destroy/keep, a secret array must be non-empty), and runtime store errors are deferred to next(err) instead of being swallowed. The code is plain ES5-style CommonJS with no static types, but every public function carries JSDoc-style @param/@return/@public/@private comments that double as documentation, and .eslintrc.yml enforces consistent style (eqeqeq, indentation, no mixed spaces/tabs, one-var).
API Design The public surface is essentially one call — app.use(session({…})) — after which req.session, req.sessionID, and req.sessionStore are simply available for the rest of the request lifecycle, with no further imports needed for the common case. Its most notable design choice is the deliberately minimal Store contract (only get/set/destroy required, touch optional), which is a stable long-lived convention rather than a technically novel mechanism, but one that has let a very large ecosystem of independent session-store packages stay compatible without coordinating with this repo. Newer additions — ‘auto’ resolution for cookie.secure/sameSite based on request TLS state, and a callback form for per-request cookie options — reduce boilerplate for reverse-proxy and multi-tenant setups. Overall this is well-worn, conventional middleware design rather than an innovative architecture.
Used by 24 apps in this directory
Blinko
Knowledge Management · Note Taking
A self-hosted, AI-powered card note-taking tool that lets you capture fleeting thoughts instantly and retrieve them with natural language search.
Countly
Analytics · Marketing
Privacy-first, self-hosted analytics and customer engagement platform with full data ownership, GDPR compliance, and AI-powered insights across mobile, web, desktop, and IoT.
Flowise
Developer Tools · Automation · No Code Platforms
Drag-and-drop visual builder for AI agents, RAG pipelines, and multi-agent systems—deploy anywhere in minutes.
FormBee
Forms Surveys
A self-hostable form backend that accepts HTML form submissions and routes them to email, Telegram, Discord, webhooks, and automation platforms — without writing any server-side code.
Ghost
CMS · Blogging
Open source headless Node.js CMS for professional publishing, paid memberships, and newsletters with a fully owned audience.
Hexabot
AI Development · Automation
Build and run agentic workflows across channels with YAML, tools, and RAG
HyperDX
Developer Tools · Analytics · Monitoring
Open source observability platform that unifies logs, traces, metrics, and session replays on ClickHouse — now the core of ClickStack.
LibreChat
Developer Tools · AI Assistants
Unite every major AI model in one self-hosted chat platform with agents, code execution, MCP tools, and enterprise authentication.
Lightdash
Analytics · Data Engineering
The open-source Looker alternative that turns your dbt project's metrics and dimensions into governed, self-serve charts and dashboards — no license key required.