Skip to content
vault logoVaultStorage
Typed browser storage and opt-in driver-neutral SQLite with portable keys, TTL, observation, and transactions.
Version
v2.2.0
Size
0.8 KB gzip
Dependencies
Zero dependencies
BrowserNode ≥22Deno
tablettlscheduleExpiredPruneisExpiredcreateMemory View all 9 exports

Why Vault?

Vault gives browser and SQLite persistence one typed schema while keeping backend guarantees explicit. Use VaultStore for portable CRUD and observation; choose IndexedDB or the opt-in SQLite subpath when you need atomic transactions or lazy iteration.

ts
// Before
localStorage.setItem('theme', JSON.stringify({ value: 'dark' }));
const theme = JSON.parse(localStorage.getItem('theme') ?? '{}').value;

// After
await store.put('preferences', { id: 'theme', value: 'dark' });
const theme = await store.get('preferences', 'theme');
FeatureVaultRaw Web StorageDexie
Bundle size0.8 KBBrowser built-inExtra dependency
Runtime dependencies
Typed schema and keysApplication-defined
Portable Memory/Web Storage APIIndexedDB only
Explicit atomic transactionsIndexedDB capability
Driver-neutral SQLiteOpt-in subpath

Use Vault when you need typed browser persistence or application-owned SQLite with one portable CRUD API and explicit storage capabilities.

Consider raw Web Storage when you only persist one or two unstructured values. Consider Dexie when you need a broader IndexedDB ecosystem.

Installation

sh
pnpm add @vielzeug/vault
sh
npm install @vielzeug/vault
sh
yarn add @vielzeug/vault

Quick Start

Define a schema, create a portable store, and dispose it with its owner.

ts
import { table } from '@vielzeug/vault';
import { createLocalStorage } from '@vielzeug/vault/local-storage';

const store = createLocalStorage({
  name: 'app-v2',
  schema: { preferences: table<{ id: string; theme: 'dark' | 'light' }>('id') },
});

try {
  await store.put('preferences', { id: 'theme', theme: 'dark' });
  console.log(await store.get('preferences', 'theme'));
} finally {
  await store.dispose();
}

Features

  • table() defines typed records with portable string or number keys.
  • /memory, /local-storage, and /session-storage return portable VaultStore instances without loading other adapters.
  • observe() emits current and changed table snapshots.
  • ttl creates validated expiration durations.
  • /indexeddb returns IndexedDbVaultStore with batch() and iterate().
  • createSQLite() is an opt-in, driver-neutral subpath for Node, Bun, and Deno SQLite drivers.
  • /indexeddb also exports defineMigration() for schema upgrades.
  • scheduleExpiredPrune() removes stale TTL entries on an owned schedule.

Documentation

See Also

  • Forge saves and restores form drafts through Vault stores.
  • Ripple owns application state that can persist through Vault.
  • Courier can populate persistent cache data.