A browser native SQL database

Run PostgreSQL-style SQL over durable browser-local data.

Minnow is a columnar SQL database for the browser. It stores data in IndexedDB or OPFS and runs queries on the device, so an application can filter, join, aggregate, and update local data without a server round trip.

import { MinnowDatabase } from "@minnowdb/core";
import { IndexedDbBlockStore } from "@minnowdb/core/storage/indexeddb";

const db = new MinnowDatabase(await IndexedDbBlockStore.open({ name: "shop" }));

await db.execute(`CREATE TABLE orders (
  order_id INTEGER PRIMARY KEY,
  customer_id INTEGER NOT NULL,
  total NUMERIC(12, 2) NOT NULL,
  placed_at TIMESTAMP NOT NULL
)`);

const { rows } = await db.query(`
  SELECT DATE_TRUNC('month', placed_at) AS month, SUM(total) AS revenue
  FROM orders
  GROUP BY DATE_TRUNC('month', placed_at)
  ORDER BY month DESC
`);

Experimental

Minnow is in 0.x, so minor releases can include API and SQL breaking changes. Stored data is stable: block format 2, snapshot format 1, IndexedDB schema 4, and OPFS layout 9 are versioned separately and locked — an incompatible future writer must use a new format number. Pin exact package versions. The versioning guide explains the policy, and the changelog lists breaking changes and migrations. Supported storage upgrades, including IndexedDB schemas 1–3 to 4 and OPFS layouts 6–8 to 9, run automatically on open; see the OPFS guide.

Why use Minnow

  • PostgreSQL-style SQL. Use familiar parameters, joins, CTEs, window functions, grouping sets, upserts, RETURNING, triggers, stored generated columns, exact decimals, JSON/JSONB, zoneless DATE, arrays, enums, sequences, and savepoints. The feature matrix names the exact supported forms and every deliberate difference.
  • Fast scans over local application data. Minnow stores compressed columns, reads only the columns a query uses, and skips blocks that cannot match. Secondary indexes speed up selective filters and ordered reads.
  • Durable and safe across tabs. Writes publish atomically to IndexedDB or OPFS. Each query sees one stable version, even while another tab commits.
  • No server or Wasm setup. Minnow is plain JavaScript. There is no database process, Wasm module, compile delay, SharedArrayBuffer, or special response header to configure.
  • Works off the UI thread. The worker client exposes the same query, write, catalog, index, migration, snapshot, and maintenance calls as the direct engine.
  • Handles larger working sets. Queries run in batches. Sorts and grouped results can spill to storage when they exceed the configured execution budget; pull-driven cursors transfer one bounded page at a time.
  • Reactive, typed views. Kysely live queries preserve inferred rows and result plugins, with keyed changes, ordered windows, and Suspense/SWR-friendly React hooks.

Choose how you query

Both interfaces use the same SQL engine and can share one database.

InterfaceUse it when
MinnowDatabaseYou want direct SQL and the smallest dependency set.
@minnowdb/kyselyYou want Kysely's type-safe PostgreSQL query-builder API.

Where Minnow fits

Minnow works well for offline tools, local dashboards, data explorers, and applications that keep their own relational data on the device. It supports both day-to-day keyed reads and writes and analytical queries over the data that accumulates.

Minnow is not a server database or a sync service. It works on one device, inside one browser's storage quota. If you need replication, multi-user access, exact SQLite file compatibility, or the full PostgreSQL server, see the comparison guide.

Start here

  • Installation — install the engine and choose a storage adapter.
  • Your first query — create tables, write rows, and run a grouped query.
  • SQL — statement APIs, supported reads and writes, full-text search, and plans.
  • Schema and migrations — define tables in TypeScript and evolve them without rewriting stored data.
  • Client adapters — connect Kysely to Minnow's SQL engine.
  • Extensions — live queries, React, cursors, CSV, and NDJSON.
  • Workers and engine options — keep work off the main thread and tune memory.
  • Storage — IndexedDB, OPFS, memory, snapshots, and custom adapters.
  • Changelog — release notes, migrations, and storage compatibility.

On this page