Overview
Minimal IndexedDB storage adapter using the idb library â only ~3KB.
@localmode/idb
Minimal IndexedDB storage adapter using the idb library. A thin, promise-based wrapper around IndexedDB with typed schemas at only ~3KB.
Features
- ðŠķ ~3KB â Smallest external storage adapter
- ð Type-Safe â Full TypeScript schema definitions via
DBSchema - ð§Đ Promise-Based â Clean async/await API over raw IndexedDB
- ðïļ Typed Indexes â Collection-scoped lookups with typed index definitions
Installation
bash pnpm install @localmode/idb @localmode/core bash npm install @localmode/idb @localmode/core bash yarn add @localmode/idb @localmode/core bash bun add @localmode/idb @localmode/core Quick Start
import { IDBStorage } from '@localmode/idb';
import { createVectorDB, embed, ingest } from '@localmode/core';
import { transformers } from '@localmode/transformers';
// Create storage
const storage = new IDBStorage({ name: 'my-app' });
// Use with VectorDB
const db = await createVectorDB({
name: 'documents',
dimensions: 384,
storage,
});
// Ingest documents
const model = transformers.embedding('Xenova/bge-small-en-v1.5');
await ingest({
db,
model,
documents: [
{ text: 'Local-first AI is the future', metadata: { source: 'blog' } },
{ text: 'Privacy-preserving machine learning', metadata: { source: 'paper' } },
],
});The ingest() function is part of the RAG pipeline. It chunks, embeds, and stores documents in a single call.
Configuration
Prop
Type
Why idb?
The idb library is the thinnest possible wrapper around IndexedDB:
- ~3KB gzipped â Adds almost nothing to your bundle
- Promise-based â Replaces IndexedDB's awkward event-based API with async/await
- Typed schemas â Full
DBSchemainterface for compile-time safety - No magic â What you write is what runs; no ORM overhead
When to choose idb
Choose @localmode/idb when bundle size is your top priority and you don't need Dexie's schema
versioning or localForage's automatic driver fallback.
Typed Schema
IDBStorage uses idb's DBSchema interface for compile-time type safety on all IndexedDB operations. The schema defines four object stores with typed indexes for efficient collection-scoped lookups:
// Internal schema (handled automatically)
interface VectorDBSchema extends DBSchema {
documents: {
key: string;
value: DocumentRecord;
indexes: { collectionId: string }; // Fast per-collection queries
};
vectors: {
key: string;
value: VectorRecord;
indexes: { collectionId: string };
};
indexes: { key: string; value: IndexRecord };
collections: { key: string; value: CollectionRecord; indexes: { name: string } };
}This means all get(), put(), and delete() calls are type-checked â you get compile-time errors for invalid keys or values, unlike raw IndexedDB.
Storage Fallback
Gracefully fallback when IndexedDB is unavailable (e.g., Safari private browsing):
import { MemoryStorage } from '@localmode/core';
import { IDBStorage } from '@localmode/idb';
let storage: IDBStorage | MemoryStorage;
try {
storage = new IDBStorage({ name: 'my-app' });
await storage.open();
} catch (error) {
console.warn('IDBStorage unavailable, falling back to memory:', error);
storage = new MemoryStorage();
}Comparison
| Adapter | Package | Bundle Size | Transactions | Auto-Fallback | Best For |
|---|---|---|---|---|---|
IndexedDBStorage | @localmode/core | 0KB (built-in) | No | No | Simple apps, zero extra deps |
DexieStorage | @localmode/dexie | ~15KB | Yes | No | Production apps needing schema versioning |
IDBStorage | @localmode/idb | ~3KB | No | No | Minimal bundle size |
LocalForageStorage | @localmode/localforage | ~10KB | No | Yes | Max browser compatibility |