keyv-file
A lightweight file-based storage adapter for Keyv that persists key-value data to disk with automatic TTL expiry.
Repository Health
Technical Analysis
keyv-file is a storage adapter for Keyv, the simple key-value store abstraction, that writes cached data to a local JSON (or MessagePack) file instead of requiring an external database like Redis. It batches writes behind a configurable delay to avoid hammering the filesystem, and runs a periodic background scan to clear expired entries so TTL data doesn’t quietly bloat the file on disk.
Beyond the basic single-file mode, keyv-file supports a separated-file storage layout that writes each key to its own file inside a directory - useful when a single JSON blob would grow too large or when per-key file operations are wanted. It also ships a small makeField helper for typed, field-like access to individual keys, and works as a drop-in Keyv store for any project that already uses the Keyv API.
What You Get
- Drop-in Keyv storage adapter implementing the KeyvStoreAdapter interface
- Single-file JSON persistence with debounced, batched writes
- Optional separated-file mode storing each key as its own file for larger datasets
- Built-in TTL support with periodic background expiry scanning
- makeField helper for typed, ergonomic access to individual stored fields
- Pluggable serialize/deserialize functions (JSON by default, MessagePack supported via @keyv/serialize)
Common Use Cases
- Caching API responses or computed data in a CLI tool with no external dependencies
- Persisting session or config data for a desktop/Electron app between restarts
- Local development or testing substitute for a Redis-backed Keyv store
- Rate-limiting or throttling counters that need TTL expiry without a database
- Storing per-key state in environments with local disk scratch space but no managed cache
Under The Hood
Architecture
index.ts defines the KeyvFile class implementing Keyv’s KeyvStoreAdapter, delegating to SeparatedFileHelper (separated-file-store.ts) when opts.separatedFile is enabled, otherwise keeping an in-memory Map synced to a single JSON file via a synchronous load on construction and a debounced async save() -> setTimeout -> saveToDisk() write path. make-field.ts layers a small Field wrapper on top for typed single-key access to any Keyv-compatible store (KeyvFile, Keyv, or a plain Map), and safe-encoder.ts provides filesystem-safe filename encode/decode for separated-file mode. Module boundaries are clean, though the KeyvFile class itself branches on this.opts.separatedFile inside nearly every public method rather than splitting into two adapter implementations behind a shared interface.
Tech Stack A TypeScript library targeting Node.js (fs, fs/promises, os, path, events), with @keyv/serialize as its default JSON serializer and tslib as the only runtime dependency. Dev dependencies include keyv itself, @keyv/test-suite for adapter conformance testing, msgpackr for optional MessagePack+gzip serialization, vitest as the test runner, and typescript for compilation - the package ships a plain tsc-compiled lib/ with no bundler. A GitHub Actions publish workflow runs pnpm install and pnpm test on pushes to master.
Code Quality Tests live under test/ and use vitest plus @keyv/test-suite’s official Keyv adapter conformance suite (keyvTestSuite, keyvIteratorTests), run against three configurations - default single-file, separated-file, and separated-file with a custom MessagePack+gzip serializer - alongside a dedicated test exercising the safe filename encoder against non-ASCII keys. Error handling is centralized through a small handleIOError() helper that silently ignores expected ENOENT cases and logs everything else to console.error, which is pragmatic but not a typed error strategy. Naming is consistent and types are used throughout (Options, WrappedValue, KeyvStoreAdapter), though there’s no ESLint configuration beyond a .prettierrc, and CI runs tests but not a lint step.
API Design
The package is a small, single-purpose Keyv adapter whose entire public surface is an options object plus the standard Keyv adapter methods, so getting started requires almost no boilerplate: new Keyv({ store: new KeyvFile() }). Sensible defaults (a tmpdir path, 100ms write delay, 24-hour expiry scan) make it work out of the box, while separatedFile mode and pluggable serializers cover larger-scale needs. The makeField() helper is a nice ergonomic addition, letting one store instance be used as several typed fields without hand-rolled key namespacing, and the README documents both usage styles with copy-pasteable examples.
Used by 2 apps in this directory
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.
Promptfoo
AI Development
An open-source CLI and library for evaluating and red-teaming LLM applications — replace trial-and-error prompt engineering with systematic evals, vulnerability scanning, and CI/CD integration.