Choosing a browser database

Compare Minnow with IndexedDB, Dexie, SQLite Wasm, PGlite, and DuckDB-Wasm.

Choose Minnow when a browser application owns relational data and needs both ordinary reads and writes and analytical SQL over that data. Choose another tool when file compatibility, sync, a complete server dialect, or direct file analysis matters more.

NeedBest starting point
Local application tables with filters, joins, aggregates, search, and updatesMinnow
Small record collections fetched mainly by key or declared indexDexie or IndexedDB
The SQLite dialect, file format, extensions, or shared mobile/server migrationsSQLite Wasm
PostgreSQL query behavior, supported extensions, or ElectricSQL syncPGlite
In-browser analysis of Parquet, Arrow, or CSV filesDuckDB-Wasm
Multi-device or multi-user synchronizationA sync engine

Why choose Minnow

  • One database for application work and analysis. Primary and secondary indexes handle selective reads and writes. Columnar storage keeps scans, joins, and aggregates efficient as data grows.
  • PostgreSQL-style SQL without a PostgreSQL server. Use familiar syntax directly or through Kysely. The compatibility page lists exact matches, differences, extensions, and exclusions.
  • Small, browser-native delivery. Minnow is plain JavaScript with no Wasm compile step, SharedArrayBuffer, or cross-origin isolation requirement.
  • Durable multi-tab storage. IndexedDB and OPFS adapters publish atomic commits and give each reader a stable snapshot.
  • Control over memory and threading. Run the engine in a worker, set an execution budget, and spill large sorts and grouped results to storage.
  • Native Kysely types. @minnowdb/kysely derives its full database type from the same schema declaration Minnow migrates, including defaults, exact numeric and calendar-date boundaries, and driver-specific aggregate and built-in function results without redundant output generics.

Minnow does not provide a server, replication, multi-device sync, or compatibility with another database's file format.

Browser download size

Download size affects cold starts, and Wasm engines also compile a module before the first query.

EngineDownload (gzip)RawWasm compile step
IndexedDB00No
Minnow 0.14.0382 KiB1.31 MiBNo
SQLite Wasm 3.53.0-build1457 KiB1.03 MiBYes
PGlite 0.5.55.46 MiB16.20 MiBYes

The Minnow, SQLite Wasm, and PGlite values come from the repository's reproducible size script. It uses identical esbuild settings and includes the Wasm modules and packed runtime data each package downloads. IndexedDB is built into the browser. Minnow's number includes the engine and its larger durable adapter, OPFS; an IndexedDB build is slightly smaller, and unused adapters stay out of the application bundle. The size advantage over this SQLite Wasm build is for compressed downloads; Minnow is larger uncompressed. Sizes use binary units (1 KiB = 1,024 bytes, 1 MiB = 1,048,576 bytes). These are the installed comparison versions, not a claim about every build or the latest upstream release. Worker/client entries and optional extensions have separate download costs; see the worker guide.

IndexedDB

IndexedDB is the built-in asynchronous key-value database in every modern browser. It supports transactions and secondary indexes without adding a dependency.

Choose IndexedDB when the application stores a small number of objects and access is almost always “get this key” or “read this index.” Nothing else is smaller.

Choose Minnow when the application needs joins, grouping, aggregation, sorting, full-text search, or SQL. Minnow stores compressed columns and can run in a worker instead of turning each query into application cursor code over cloned objects.

Dexie

Dexie adds promises, schema migrations, compound indexes, a query API, and live queries to IndexedDB. Dexie Cloud adds hosted sync.

Choose Dexie when indexed record access is the main workload, bundle size is critical, or you want its mature migration or sync ecosystem.

Choose Minnow when the same local data also needs relational and analytical queries. Minnow plans SQL across tables and reads the columns and blocks a query needs instead of materializing every record as a JavaScript object.

The same broad trade-off applies to idb, localForage, and direct IndexedDB wrappers.

SQLite Wasm

SQLite Wasm brings SQLite's mature SQL engine, file format, extensions, indexes, and tooling into the browser.

Choose SQLite Wasm when the application needs SQLite compatibility, existing SQLite migrations, broad index support, extensions, or the ability to move the same database file among browser, mobile, and server environments. Extensions must be included in, or supported by, the chosen Wasm build.

Choose Minnow when browser-local analytical reads, compressed column storage, a smaller plain JavaScript download, and simple multi-tab persistence matter more. Minnow uses IndexedDB or OPFS without requiring cross-origin isolation headers. SQLite’s SAH-pool VFS also avoids those headers; its standard OPFS VFS requires them. Concurrency differs between these VFS choices.

SQLite’s B-tree design suits point reads and writes; Minnow’s columnar design suits scans and aggregates. That does not establish a universal performance ranking or competitor parity. Run the live benchmarks for the workload and browser you care about.

PGlite

PGlite runs PostgreSQL in WebAssembly with PostgreSQL query behavior and a supported extension set, including pgvector. It is an embedded engine with one exclusive database connection, rather than a PostgreSQL server. Its multi-tab worker shares that instance across tabs, and its live-query extension provides reactive results. ElectricSQL provides a separate sync integration.

Choose PGlite when PostgreSQL query behavior, supported extensions, shared server SQL, or ElectricSQL sync is the requirement.

Choose Minnow when the application needs a much smaller download, no Wasm startup, columnar queries, and durable access from several tabs. Minnow supports a documented embedded PostgreSQL dialect rather than the complete server.

DuckDB-Wasm

DuckDB-Wasm is a columnar analytics engine that reads Parquet, Arrow, and CSV directly. It also supports SQL mutations and OPFS persistence; call CHECKPOINT to flush writes and observe its exclusive file-handle constraints.

Choose DuckDB-Wasm when the task is analysis over files or a SQL surface built for analytical tooling. Browser memory and the chosen Wasm build still bound the dataset size.

Choose Minnow when the data is an application's own durable state and users also insert, update, and delete individual rows. Minnow provides IndexedDB and OPFS persistence, atomic multi-tab writes, and background maintenance around that workload.

Sync engines

ElectricSQL, Zero, Triplit, InstantDB, PowerSync, Jazz, and CRDT libraries solve synchronization between devices or users. Minnow does not. Choose a sync product when replication and conflict resolution are requirements.

Minnow's SQL and snapshot APIs can serve as building blocks for a future sync layer, but no sync adapter ships with the project.

Minnow's limits

  • Minnow is in 0.x, so minor releases can include API and SQL breaking changes. Block format 2, snapshot format 1, IndexedDB schema 4, and native OPFS layout 9 are separately versioned and locked. Supported storage upgrades run automatically on open, including IndexedDB schemas 1–3 to 4 and OPFS layouts 6–8 to 9; see the OPFS guide.
  • Its SQL dialect is an embedded PostgreSQL subset, not the PostgreSQL server.
  • UPDATE and DELETE require row identity: a primary key or one inline unique column.
  • Secondary indexes support scalar and composite left-prefix equality, IN, range filtering, and selected ordered or covering reads. They do not provide PostgreSQL's full access-method system.
  • The engine runs in browsers, not Node.js.
  • There is no replication, server process, or multi-device sync.

Try Minnow in the live SQL and TypeScript console. The benchmarks run Minnow, SQLite Wasm, and PGlite on your machine and verify every answer before reporting a time.

On this page