async-idb-orm
Promise-based IndexedDB wrapper with an ORM-like API and support for Active Records, relations, and migrations.
Build offline-first web apps with a type-safe, ergonomic API. async-idb-orm gives you collections, key ranges, events, transactions, relations, selectors, foreign keys, async iteration, serialization, and migrations—without leaving the comfort of promises and TypeScript.
What’s in the docs
- Getting Started — Install, define collections, and run your first queries
- Key Ranges — Use the
rangetagged template for index queries and iteration - Events — Listen to
write,delete, andclear; optional cross-tab relay - Active Records — Work with live objects and call
.save()/.delete() - Transactions — Wrap multi-step updates with
db.transaction() - Relations — One-to-one and one-to-many with
with,where,limit, nesting - Selectors — Derived, reactive data that updates when collections change
- Foreign Keys — Pseudo-FKs with cascade/restrict and parent checks
- Async Iteration —
for awaitover collections and indexes - Serialization — Store types IndexedDB doesn’t support natively
- Migrations — Version upgrades and schema changes via
onUpgrade - Block Resolution — How version conflicts across tabs are handled
Quick peek
import { idb, Collection } from "async-idb-orm"
type User = { id: string; name: string; age: number }
const users = Collection.create<User>()
.withKeyPath("id")
.withTransformers({
create: (dto) => ({ ...dto, id: crypto.randomUUID() }),
})
const db = idb("my-app", { schema: { users }, version: 1 })
const user = await db.collections.users.create({ name: "Alice", age: 30 })
await db.collections.users.update({ ...user, age: 31 })
const found = await db.collections.users.find(user.id)
Hit Getting Started next to wire this into your app.