idb-keyval
A tiny promise-based key-value store built on IndexedDB for the browser
Repository Health
Technical Analysis
idb-keyval is a minimal, promise-based wrapper around the browser’s IndexedDB API that exposes a familiar key-value interface — get, set, del, keys, values, entries — instead of IndexedDB’s verbose event-driven API. It ships as an ultra-small, tree-shakeable ES module (as little as ~295 bytes brotli’d for get/set alone) with batched setMany/getMany/delMany helpers, an atomic update() helper for race-free read-modify-write cycles, and support for custom named stores when the shared default store isn’t enough.
Because it’s a thin layer over native IndexedDB rather than a full ORM, it inherits IndexedDB’s persistence, storage quotas, and structured-clone value support (objects, arrays, dates, blobs) without adding parsing or serialization overhead. It’s commonly reached for wherever localStorage’s synchronous, string-only API is too limiting — offline-first web apps, PWAs, and client-side caches that need to store structured data asynchronously.
What You Get
- Promise-based get/set/del/update/clear API over IndexedDB
- Batched setMany/getMany/delMany for faster, atomic bulk writes and reads
- keys()/values()/entries() bulk readers with fast-path getAll()/getAllKeys() support
- createStore() for named custom databases/stores beyond the default keyval-store
- Sub-kilobyte, tree-shakeable ESM build plus legacy compat and UMD bundles
Common Use Cases
- Offline-first web apps and PWAs caching structured data client-side
- Replacing localStorage where synchronous, string-only storage is too limiting
- Persisting large blobs, files, or images in the browser without a server round-trip
- Client-side caching layers for API responses or computed state across sessions
Under The Hood
Architecture — The entire library lives in a single 277-line src/index.ts module. Each store is represented by a UseStore function type that takes a transaction mode (“readonly”/“readwrite”) and a callback receiving an IDBObjectStore; createStore() closes over a lazily-opened, cached IDBDatabase promise (getDB()) and re-opens it if Safari closes the connection unexpectedly. promisifyRequest() is the single bridge point that turns any IDBRequest or IDBTransaction’s success/complete and error/abort events into a resolved or rejected Promise, and every exported function (get, set, del, update, setMany, getMany, delMany, clear, keys, values, entries) is built on top of that one primitive plus the shared store callback pattern. Bulk readers (keys/values/entries) branch on a fast path using native getAll()/getAllKeys() when available and fall back to manual cursor iteration (eachCursor()) for older engines.
Tech Stack — Written in TypeScript and built with Rollup (rollup.config.js), using @rollup/plugin-typescript for compilation, @rollup/plugin-babel with an IE10 preset to produce compat/UMD legacy bundles, and @rollup/plugin-terser for minification; glob and del handle build housekeeping and a custom size-report script tracks brotli’d bundle size. The package.json exports map ships ESM, CJS, compat, and UMD outputs from one source tree. There are zero runtime dependencies, and .nvmrc/pnpm-lock.yaml pin the dev toolchain to Node 22.
Code Quality — test/index.ts is a 553-line Mocha + Chai suite that runs in a real browser (via test/index.html) against a live IndexedDB, covering get/set/del/clear/update/setMany/getMany/delMany/keys/values/entries plus isolation between custom stores, and it layers in compile-time type assertions using conditional-type-checks. Errors are not wrapped in custom classes — they propagate as the native IDBRequest.error via each function’s promise rejection, which is consistent but leaves error messages entirely up to the browser’s IndexedDB implementation. Naming is deliberately terse and consistent (get/set/del rather than delete, to dodge the reserved word), and every exported function carries a JSDoc block with parameter descriptions.
API Design — The public surface is about a dozen flat top-level functions sharing one optional trailing customStore parameter, so the common case (import { get, set } from ‘idb-keyval’) needs zero configuration, while advanced multi-store usage only requires calling createStore() once. Function names mirror Map/Storage conventions (get/set/del/keys/values/entries), which keeps the API instantly familiar, and the update() helper solves a real correctness pitfall (racy get-then-set) that the README calls out explicitly with a before/after example.
Used by 13 apps in this directory
AFFiNE
Productivity · Project Management · Note Taking
Write, draw, and plan in one infinite canvas — the open-source alternative to Notion and Miro that keeps your data yours.
BrowserOS
Browser · AI Assistants
The open-source agentic Chromium browser with native AI agents, MCP server, and visual workflow automation — your data never leaves your machine.
Enso
Analytics · Data Engineering · Low Code Platforms
A visual and textual programming platform for data prep and analysis where the node graph and the underlying Enso code are always perfectly in sync, built by an Alteryx co-founder on a GraalVM engine.
GitButler
Developer Tools · Devops · AI Development
Git, but better — a modern version control client with stacked branches, parallel workflows, unlimited undo, and first-class support for AI-powered development.
GraphQL Hive
Developer Tools · Devops · Monitoring
Open-source GraphQL schema registry and observability platform with breaking change detection, federation support, and CI/CD integration for teams of any size.
lila (Lichess)
Community
The forever-free, ad-free, open-source chess server powering millions of real-time games, AI analysis, puzzles, and tournaments worldwide.
Openship
Devops · Hosting Control Panel
Openship is an open-source, self-hostable deployment platform that points at a repo and builds, ships, routes, and TLS-terminates the app — driven from a desktop app, web dashboard, or CLI.
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.
Refly
No Code Platforms · AI Development · Automation
Build deterministic, versioned agent skills from natural language—run them anywhere from Claude Code to Slack.