LocalMode
idb

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 DBSchema interface 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

AdapterPackageBundle SizeTransactionsAuto-FallbackBest For
IndexedDBStorage@localmode/core0KB (built-in)NoNoSimple apps, zero extra deps
DexieStorage@localmode/dexie~15KBYesNoProduction apps needing schema versioning
IDBStorage@localmode/idb~3KBNoNoMinimal bundle size
LocalForageStorage@localmode/localforage~10KBNoYesMax browser compatibility

Next Steps

On this page