npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

express-lite-nosql-session

v1.0.0

Published

Persistent session store for express-session using lite-nosql (file-based, no external DB required)

Readme

express-lite-nosql-session

Persistent session store for express-session backed by lite-nosql.

No MySQL. No Redis. No Postgres. No native binaries.
Sessions are persisted to disk as plain files — ideal for shared hosting, small VPSs, or any environment without an external database.


Features

  • ✅ Fully compatible with express-session Store interface
  • store instanceof session.Store is true at runtime (extends EventEmitter)
  • ✅ Persistent across server restarts
  • ✅ Automatic TTL expiry + background garbage collection
  • ✅ Optional AES-256-GCM encryption at rest
  • ✅ WAL + snapshot compaction via lite-nosql
  • ✅ Zero native dependencies
  • ✅ TypeScript types — aligned with runtime
  • ✅ ESM (Node.js 18+)

Installation

npm install express-lite-nosql-session lite-nosql express-session

Quick Start

import express from "express";
import session from "express-session";
import LiteNoSQLStore from "express-lite-nosql-session";

const app = express();

app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  store: new LiteNoSQLStore({ pasta: "./dados" }),
  cookie: { maxAge: 86_400_000 }, // 24 h
}));

Full Example with All Options

import session from "express-session";
import LiteNoSQLStore from "express-lite-nosql-session";

const store = new LiteNoSQLStore({
  pasta: "./dados",               // directory for db files (outside public web root)
  colecao: "sessions",            // collection name
  modoDuravel: true,              // fsync on every write
  limiteWAL: 1_048_576,           // compact WAL at 1 MB
  ttlPadraoMs: 86_400_000,        // 24 h default TTL
  intervaloLimpezaMs: 300_000,    // GC every 5 minutes
  compactarAposLimpeza: false,    // compact after each GC pass
  debug: false,
  chaveEncriptacao: process.env.SESS_DB_KEY, // optional encryption
});

app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  store,
  cookie: { maxAge: 86_400_000 },
}));

Options Reference

| Option | Type | Default | Description | |---|---|---|---| | pasta | string | required | Directory where session files are stored | | colecao | string | "sessions" | lite-nosql collection name | | modoDuravel | boolean | true | fsync on every write (safer, slightly slower) | | limiteWAL | number | 1_048_576 | WAL size (bytes) before automatic compaction | | ttlPadraoMs | number | 86_400_000 | Default TTL (ms) when no cookie expiry is set | | intervaloLimpezaMs | number | 300_000 | GC interval in ms | | compactarAposLimpeza | boolean | false | Compact after each GC pass | | debug | boolean | false | Verbose internal logging | | chaveEncriptacao | string | — | AES-256-GCM key to encrypt WAL + snapshot |


express-session Compatibility

LiteNoSQLStore extends session.Store (which itself extends EventEmitter) at runtime via createRequire, because express-session is a CommonJS module.

This means:

import session from "express-session";
import LiteNoSQLStore from "express-lite-nosql-session";

const store = new LiteNoSQLStore({ pasta: "./dados" });
console.log(store instanceof session.Store); // true
console.log(typeof store.emit);             // "function"

The TypeScript declaration (extends Store) matches this runtime behaviour exactly.


TTL and Session Expiry

expiresAt is calculated with this priority:

  1. session.cookie.expires (absolute Date)
  2. session.cookie.maxAgeDate.now() + maxAge
  3. Fallback: Date.now() + ttlPadraoMs

On get(), expired sessions return null and are removed lazily (non-blocking).

touch() only writes expiresAt and sess.cookie — not the full session — to minimise WAL write amplification.


Garbage Collection

The background GC runs every intervaloLimpezaMs and:

  1. Queries sessions where expiresAt <= Date.now()
  2. Removes them in batches of 50 (avoids blocking the event loop)
  3. Optionally calls compactar() if compactarAposLimpeza: true

The timer is created with .unref() so it never prevents the process from exiting.


WAL Compaction

lite-nosql writes all mutations to an append-only WAL, which grows over time. Compaction merges the WAL into a snapshot and resets it.

  • Automatic: triggers when WAL exceeds limiteWAL (default 1 MB).
  • After GC: set compactarAposLimpeza: true for session-heavy applications.
  • Before backup: call await store._col.compactar() for a clean snapshot.

Encryption at Rest

new LiteNoSQLStore({
  pasta: "./dados",
  chaveEncriptacao: process.env.SESS_DB_KEY, // min 8 characters
});

⚠️ Never delete .db.salt or other auxiliary files from the data folder — they are required to decrypt existing data.
⚠️ Store the key in an environment variable, never hardcode it.


Graceful Shutdown

Always call store.close() before exiting to flush pending writes and cancel the GC timer:

async function shutdown(signal) {
  console.log(`${signal} received — shutting down`);
  await store.close();
  process.exit(0);
}

process.on("SIGINT",  () => shutdown("SIGINT"));
process.on("SIGTERM", () => shutdown("SIGTERM"));

Validating the Package Before Publishing

Use npm pack to simulate exactly what gets published to npm:

# Shows the list of files that would be included
npm pack --dry-run

# Creates the real tarball for inspection
npm pack
tar -tf express-lite-nosql-session-1.0.0.tgz

Only files listed in "files" in package.json are included:

  • src/index.js
  • src/index.d.ts
  • README.md

Single Process Only

⚠️ lite-nosql uses file-level locking and an in-memory cache. Running multiple Node.js processes pointing at the same pasta directory (e.g. PM2 cluster mode) is not supported and will cause data corruption.

For multi-process deployments, use a network-capable store (Redis, Postgres, etc.).


Files on Disk

dados/
  sessions.snapshot.json   ← compact state
  sessions.wal.log         ← append-only journal
  sessions.lock            ← temporary lock during compaction

Place pasta outside your public web root so these files are not accessible over HTTP.


Limitations

  • All sessions in memory: lite-nosql caches everything in RAM. Not suitable for very large numbers of concurrent long-lived sessions.
  • Single process only: see above.
  • No cross-collection transactions.
  • ESM only: lite-nosql is ESM. CommonJS projects must use await import(...).

CommonJS Usage

Because lite-nosql is ESM-only, CommonJS projects must use dynamic import:

// CommonJS
const { LiteNoSQLStore } = await import("express-lite-nosql-session");

Or migrate to ESM by adding "type": "module" to your package.json.


Running the Example

cd examples/express-basic
npm install
SESSION_SECRET=mysecret node server.js
# Login
curl -c cookies.txt -X POST http://localhost:3000/login \
  -H "Content-Type: application/json" -d '{"userId":"123"}'

# Read session
curl -b cookies.txt http://localhost:3000/me

# Logout
curl -b cookies.txt -X POST http://localhost:3000/logout

License

MIT