Node.js · NAPI · local storage

Choosing an embedded database for Node.js

There is no universal “best” Node.js database. A desktop app, API server, local RAG process, test runner, and offline utility need different query models and packaging boundaries.

Short answer: choose SQLite for broad compatibility and conventional SQL, DuckDB for local analytics, key-value engines for simple ordered access, and a hybrid engine such as MongrelDB when operational writes, SQL scans, text, and vectors must share one local store.

Choose the runtime boundary first

BoundaryStrengthCost
Native Node addonIn-process calls, direct buffers, low latencyPlatform binaries, ABI/toolchain packaging, blocking-I/O discipline
WASMPortable sandbox and simpler distribution in supported environmentsFilesystem, threading, memory, and native-library limits
Pure JavaScriptEasy installation and debuggingCPU-heavy indexing and persistence compete on the JS runtime
Local daemonMany processes/languages share one warm databaseNetwork protocol, lifecycle, auth, and service management

Do not select a database from benchmark charts before deciding which boundary your product can ship and operate.

Map the workload to an engine family

  • Relational application state: SQLite remains the default benchmark because of maturity, portability, tooling, and a huge ecosystem.
  • Local analytical scans: DuckDB is optimized for analytical SQL and columnar execution.
  • Ordered key-value access: LevelDB/RocksDB-style engines provide a smaller data model with predictable sorted-key behavior.
  • Reactive browser/local-first data: synchronization and browser support may matter more than server-side SQL.
  • Operational plus AI retrieval: evaluate transaction semantics, vector indexes, lexical search, filters, and reranking together.

MongrelDB's Node.js boundary

MongrelDB ships a native NAPI addon for Node.js 22 or newer. The embedded Database API owns a local root in-process. RemoteDatabase connects to mongreldb-server when multiple processes need one owner. Published prebuilt addon binaries currently cover Linux x64 and arm64; other platforms build from source or use the daemon client.

const { Database, ColumnType } = require("@visorcraft/mongreldb");

const db = Database.withPath("./app-data");
db.createTable("events", {
  columns: [
    { id: 1, name: "id", ty: ColumnType.Int64,
      primaryKey: true, nullable: false },
    { id: 2, name: "kind", ty: ColumnType.Bytes,
      primaryKey: false, nullable: false }
  ],
  indexes: []
});

const events = db.table("events");
events.put([
  { columnId: 1, int64: 1n },
  { columnId: 2, text: "startup" }
]);
events.commit();

Writes require an explicit commit for durability. Async variants move blocking work to the NAPI blocking pool. SQL runs through DataFusion and returns Arrow IPC bytes, which Node can decode with Apache Arrow.

Questions that expose hidden costs

  1. Does installation succeed on every OS and CPU you ship?
  2. Can the engine recover after process termination during commit?
  3. Does it enforce one owner per storage root, and how do worker processes share access?
  4. Are 64-bit identifiers returned without JavaScript number truncation?
  5. Can large result sets move as batches rather than per-cell callbacks?
  6. How are backups coordinated with open handles?
  7. Can queries be cancelled and bounded?
  8. What migration and schema tooling exists?

MongrelDB returns RowIds, counts, and epochs as BigInt, and Arrow IPC avoids per-cell object construction for analytical result paths.

Run a vertical evaluation

Build one narrow production-shaped path: create schema, write a transaction, restart, query by your most important predicate, scan a representative projection, take a backup, and restore it. Add vector search only if the product needs it. Measure package size and installation failure rate alongside latency.

Node-specific rule: a fast native engine can still make an application unresponsive if synchronous calls run on the event loop. Use the addon's async variants for blocking I/O in latency-sensitive servers.
Free companion

MongrelDB Viewer

Open the same database outside your Node application to inspect schema, rows, indexes, SQL, and maintenance.

Multi-engine development

Mongrel by VisorCraft

Use Mongrel when the Node application also touches PostgreSQL, MongoDB, Redis, containers, Kubernetes, remote shells, or HTTP APIs.

Sources