Skip to content

Repository files navigation

sqlite-cache

A simple, TTL-aware, size-bounded persistent cache for Node.js backed by SQLite via node-sqlite-map. No external database dependencies — just a file (or :memory:).

Requirements

  • Node.js >= 22.5.0 (for node:sqlite)

Installation

npm install sqlite-cache
# or
pnpm add sqlite-cache

Quick Start

import{SQLiteCache}from"sqlite-cache"constcache=newSQLiteCache({path: "./cache.db"})cache.set("user:1",{name: "Kyle",role: "admin"})cache.get("user:1")// { name: "Kyle", role: "admin" }cache.has("user:1")// truecache.size// 1

Use :memory: for a non-persistent in-memory cache:

constcache=newSQLiteCache({path: ":memory:"})

API

Constructor

newSQLiteCache<Keyextendsstring,Valueextendsobject>(options: CacheOptions)

CacheOptions

OptionTypeDefaultDescription
pathstringPath to SQLite database file, or ":memory:"
ttlnumber60000Time-to-live in milliseconds
maxnumber100Maximum number of live entries

Core Methods

set(key, value): this

Inserts or replaces an entry with a fresh TTL. Automatically evicts expired and overflow entries before inserting. Returns this for chaining.

cache.set("a",{x: 1}).set("b",{x: 2})

get(key): Value | null

Returns the value if the key exists and has not expired, otherwise null.

cache.get("a")// { x: 1 }cache.get("z")// null

has(key): boolean

Returns true if the key exists and is not expired.

cache.has("a")// true

delete(key): boolean

Removes the entry. Returns true if it existed, false otherwise.

cache.delete("a")// truecache.delete("a")// false

clear(): void

Removes all entries (including expired ones).

cache.clear()cache.size// 0

Iteration

All iteration methods only yield live (non-expired) entries.

keys(): IterableIterator<Key>

for(constkeyofcache.keys())console.log(key)console.log([...cache.keys()])// ["a", "b"]

values(): IterableIterator<Value>

console.log([...cache.values()])// [{ x: 1 }, { x: 2 }]

entries(): IterableIterator<[Key, Value]>

console.log([...cache.entries()])// [["a", { x: 1 }], ["b", { x: 2 }]]

forEach(callback): void

cache.forEach((value,key,cache)=>{console.log(key,value)})

[Symbol.iterator]()

Makes the cache directly iterable — equivalent to entries().

for(const[key,value]ofcache){console.log(key,value)}

Properties

size: number

Returns the count of live (non-expired) entries.

cache.size// 2

Eviction

Eviction happens automatically on every set() call:

  1. Expired entries are removed first.
  2. Overflow entries are removed oldest-first if the live count exceeds max.

Type Parameters

SQLiteCache<Keyextendsstring,Valueextendsobject>
ParameterConstraintDescription
KeystringKey type — must be a string
ValueobjectValue type — must be a plain object (JSON-serializable)

Exported Types

exporttypeCacheOptions={path: stringmax?: numberttl?: number}exporttypeCacheEntry<V>={value: Vexpires: numbercreatedAt: number}

Errors

All validation errors throw SqliteCacheError:

import{SqliteCacheError}from"sqlite-cache"try{cache.set(""asany,{x: 1})}catch(err){if(errinstanceofSqliteCacheError){console.error(err.message)// "Cache key must be a valid string"}}

Examples

API response cache

constcache=newSQLiteCache<string,{data: unknown}>({path: "./api-cache.db",ttl: 30_000,max: 500})asyncfunctionfetchUser(id: string){constcached=cache.get(`user:${id}`)if(cached)returncached.dataconstdata=awaitapi.getUser(id)cache.set(`user:${id}`,{ data })returndata}

Session store

constsessions=newSQLiteCache<string,{userId: string;role: string}>({path: "./sessions.db",ttl: 3_600_000,// 1 hourmax: 1000})sessions.set(sessionToken,{userId: "42",role: "admin"})sessions.get(sessionToken)// { userId: "42", role: "admin" }

License

MIT — see LICENSE for details.

Links

ResourceURL
GitHubhttps://github.com/xcfio/sqlite-cache
npmhttps://www.npmjs.com/package/sqlite-cache
Issueshttps://github.com/xcfio/sqlite-cache/issues

Made with ❤️ by xcfio

About

A simple, TTL-aware, size-bounded persistent cache for Node.js

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages