Installation

LocalDB Simulator requires Node.js 18+ and pnpm / npm / yarn. No other system dependencies needed.

# Install globally (recommended)
$ npm install -g localdb-simulator

# Verify installation
$ lds --version
0.1.0

$ lds --help

Two binary names are registered: lds (shorthand) and localdb-simulator (full name). Both point to the same entry point.

Node.js 18+ required. PostgreSQL emulator uses @electric-sql/pglite (WebAssembly) which requires the Web Crypto API available in Node 18+.

Quick Start

1. Create a config file

Run lds init in your project directory to generate a localdb-simulator.yaml:

$ cd my-project
$ lds init
✔ Created localdb-simulator.yaml

2. Start services

$ lds start
✔ redis     running  127.0.0.1:6379
✔ postgres  running  127.0.0.1:5432
◆ Dashboard http://127.0.0.1:8080

3. Copy connection strings

Click the Copy .env button in the dashboard, or use the connection strings below in your application:

# .env
REDIS_URL=redis://127.0.0.1:6379
DATABASE_URL=postgresql://postgres@127.0.0.1:5432/myapp_dev
MONGODB_URI=mongodb://127.0.0.1:27017/myapp_dev

4. Stop when done

$ lds stop
✔ redis stopped
✔ postgres stopped
✔ mongodb stopped

Configuration

LocalDB Simulator is configured via a localdb-simulator.yaml file in your project root. All changes require a service restart to take effect.

Full config reference

version: "1"

services:

  # ── Redis ────────────────────────────────────────
  redis:
    enabled: true          # enable/disable this service
    port: 6379            # TCP port to bind (127.0.0.1 only)
    persistence: false   # true → snapshot to disk every 5s
    data_dir: ./.localdb/redis  # required when persistence: true
    password: ""          # empty = no auth (NOAUTH)
    max_memory_mb: 0     # 0 = unlimited; >0 → OOM guard

  # ── PostgreSQL ───────────────────────────────────
  postgres:
    enabled: true
    port: 5432
    persistence: true
    data_dir: ./.localdb/postgres
    databases:           # list of database names to create
      - myapp_dev
      - myapp_test
    user: postgres       # superuser name
    password: ""         # empty = trust mode (no password)

dashboard:
  port: 8080            # web dashboard port
  open_on_start: true  # auto-open browser

Config options reference

KeyTypeDefaultDescription
enabledbooleantrueWhether to start this service on lds start
portnumbervariesTCP port. Must not conflict with other services or running databases.
persistencebooleanfalsePersist data to disk. Requires data_dir.
data_dirstringDirectory for persistent data. Created automatically if missing.
passwordstring""Empty string = no authentication required.
databasesstring[]["postgres"]PostgreSQL only. List of database names to initialise.
Tip: Commit localdb-simulator.yaml to your repo so the whole team uses the same ports and database names. Add .localdb/ to .gitignore.

CLI Reference

All commands are available as both lds <command> and localdb-simulator <command>.

If the server is not running when you run any command, the CLI starts it automatically in the background.

lds start [service]

Start all enabled services, or a specific service by name.

# Start all services defined in localdb-simulator.yaml
$ lds start

# Start only Redis
$ lds start redis

# Start only PostgreSQL
$ lds start postgres

The server process stays running in the background. The dashboard is available at http://127.0.0.1:8080.

lds stop [service]

Stop all services (and the server), or stop a specific service.

$ lds stop          # stop everything + server
$ lds stop redis    # stop only Redis, keep server running

lds status

Show a status table of all services with port, uptime, and memory usage.

$ lds status
  NAME      STATUS   PORT   UPTIME   MEMORY
  redis     running  6379   2m 14s   4.2 MB
  postgres  running  5432   2m 14s   38.1 MB

lds logs <service> [options]

Stream logs from a service in real time. Press Ctrl+C to stop.

$ lds logs redis
$ lds logs postgres
$ lds logs redis --tail 200   # show last 200 lines, then stream
FlagDescription
--tail <n>Show last n log lines before streaming

lds restart [service]

Restart all services or a specific one. Data is preserved.

$ lds restart
$ lds restart redis

lds init

Create a localdb-simulator.yaml in the current directory. Aborts if the file already exists.

$ lds init
✔ Created localdb-simulator.yaml

Exit codes

CodeMeaning
0Success
1General error (service failed, network error, etc.)
2Config error (invalid YAML, unknown service name, etc.)

Redis Emulator Ready

The Redis emulator implements the full RESP (REdis Serialization Protocol) over TCP. It is wire-compatible with ioredis, redis (node-redis), and any other RESP client.

Connection

// ioredis
import Redis from 'ioredis';
const redis = new Redis('redis://127.0.0.1:6379');

// With password
const redis = new Redis('redis://:mypassword@127.0.0.1:6379');

// node-redis
import { createClient } from 'redis';
const client = createClient({ url: 'redis://127.0.0.1:6379' });
await client.connect();

Supported commands

CategoryCommands
StringsGET SET DEL EXISTS MGET MSET INCR DECR INCRBY DECRBY INCRBYFLOAT APPEND STRLEN GETSET SETNX SETEX PSETEX GETEX GETDEL SETRANGE GETRANGE
HashesHGET HSET HDEL HEXISTS HGETALL HKEYS HVALS HLEN HMGET HMSET HINCRBY HINCRBYFLOAT HSETNX HRANDFIELD
ListsLPUSH RPUSH LPOP RPOP LLEN LRANGE LINDEX LSET LINSERT LREM LTRIM LMOVE LPOS
SetsSADD SREM SISMEMBER SMISMEMBER SMEMBERS SCARD SUNION SINTER SDIFF SUNIONSTORE SINTERSTORE SDIFFSTORE SRANDMEMBER SPOP SMOVE
Sorted SetsZADD ZREM ZSCORE ZCARD ZRANK ZREVRANK ZINCRBY ZRANGE ZREVRANGE ZRANGEBYSCORE ZREVRANGEBYSCORE ZCOUNT ZPOPMIN ZPOPMAX ZRANDMEMBER ZUNIONSTORE ZINTERSTORE
TTLEXPIRE PEXPIRE EXPIREAT PEXPIREAT TTL PTTL PERSIST
Pub/SubSUBSCRIBE UNSUBSCRIBE PUBLISH PSUBSCRIBE PUNSUBSCRIBE
ServerPING SELECT DBSIZE FLUSHDB FLUSHALL KEYS SCAN INFO OBJECT TYPE RENAME RENAMENX COPY WAIT OBJECT REFCOUNT OBJECT IDLETIME

Persistence

Enable persistence in config to snapshot data to LevelDB every 5 seconds:

redis:
  persistence: true
  data_dir: ./.localdb/redis
Note: SELECT (multiple databases 0–15) is supported. The data browser shows keys for a selected DB index.

PostgreSQL Emulator Ready

Powered by pglite — a WebAssembly build of real PostgreSQL 16 embedded in Node.js. Clients connect via the standard PostgreSQL wire protocol; no special drivers needed.

Connection

// node-postgres (pg)
import { Pool } from 'pg';
const pool = new Pool({
  host: '127.0.0.1',
  port: 5432,
  database: 'myapp_dev',
  user: 'postgres',
});

// With connection string
const pool = new Pool({
  connectionString: 'postgresql://postgres@127.0.0.1:5432/myapp_dev'
});

// Prisma — datasource in schema.prisma
// datasource db {
//   provider = "postgresql"
//   url      = env("DATABASE_URL")
// }
// DATABASE_URL=postgresql://postgres@127.0.0.1:5432/myapp_dev

Multi-database support

Define multiple databases in config. Each database is a separate pglite instance:

postgres:
  enabled: true
  databases:
    - myapp_dev
    - myapp_test    # isolated DB for tests
    - analytics

Authentication

ConfigAuth methodConnection
password: ""Trust (no password)postgresql://postgres@127.0.0.1:5432/db
password: "secret"MD5postgresql://postgres:secret@127.0.0.1:5432/db

Supported features

  • DDL: CREATE/DROP TABLE, INDEX, SCHEMA, SEQUENCE
  • DML: SELECT, INSERT, UPDATE, DELETE with WHERE, JOIN, GROUP BY, ORDER BY
  • Transactions: BEGIN / COMMIT / ROLLBACK
  • Extended query protocol (prepared statements, parameterised queries)
  • Data types: JSONB, BOOLEAN, TIMESTAMPTZ, UUID, ARRAY, NUMERIC
  • Functions, aggregates, CTEs, window functions
pglite: ~95% of standard PostgreSQL SQL is supported. Complex features like logical replication, extensions (PostGIS, pgvector), and foreign data wrappers are not available.

SQLite Emulator Coming in Phase 3

SQLite is an embedded database — it has no client-server wire protocol. The SQLite emulator manages .db files and exposes data through the dashboard's data browser. Clients access the file directly using better-sqlite3.

SQLite does not bind a TCP port. There is no connection URL. Your app uses the file path directly: file:./.localdb/sqlite/myapp_dev.db

Planned config

sqlite:
  enabled: true
  data_dir: ./.localdb/sqlite
  databases:
    - myapp_dev

MongoDB Emulator Ready

Powered by mongodb-memory-server, which downloads the official mongod binary for your platform on first run (~77 MB, cached in ~/.cache/mongodb-binaries). 100% wire-compatible — use the standard mongodb driver without modification.

First-run binary download: When MongoDB first starts, mongodb-memory-server downloads the official mongod binary for your OS (~77 MB). This happens once and is cached. Subsequent starts are instant (~100 ms). Set MONGOMS_DOWNLOAD_DIR to a shared path to reuse across projects.

Connecting

// Official mongodb driver (Node.js)
import { MongoClient } from 'mongodb';

const client = new MongoClient('mongodb://127.0.0.1:27017');
await client.connect();
const db = client.db('myapp_dev');

// Mongoose
await mongoose.connect('mongodb://127.0.0.1:27017/myapp_dev');

# .env
MONGODB_URI=mongodb://127.0.0.1:27017/myapp_dev

Configuration

mongodb:
  enabled: true
  port: 27017
  persistence: false        # true → WiredTiger engine, data survives restart
  data_dir: ./.localdb/mongodb  # required when persistence: true
  databases:
    - myapp_dev
    - myapp_test
FieldTypeDefaultDescription
enabledbooleantrueEnable / disable the emulator.
portnumber27017TCP port to bind on 127.0.0.1.
persistencebooleanfalseIf true, uses WiredTiger engine with data_dir for durable storage.
data_dirstringDirectory for persistent data. Required when persistence: true.
databasesstring[]["test"]Logical database names exposed in the data browser. The wire protocol allows any database name regardless of this list.

Supported features

  • Full CRUD: insertOne/Many, findOne/find, updateOne/Many, deleteOne/Many, replaceOne
  • Aggregation pipeline ($match, $group, $sort, $project, $lookup, …)
  • Indexes: createIndex, unique indexes, compound indexes
  • Multi-database — data is fully isolated between databases
  • Persistence — WiredTiger storage engine, data survives restarts
  • Mongoose, Prisma, and any driver that targets the MongoDB wire protocol
Tip: The emulator is an unmodified mongod binary, so compatibility is effectively 100% for MongoDB 8.x features.

Web Dashboard

The dashboard is available at http://127.0.0.1:8080 as soon as lds start runs. It provides real-time visibility into your local services.

Service cards

Each service has a card showing:

  • Status badge (running / stopped / error) + connection string
  • Live metrics: commands/sec, memory usage, active keys / databases
  • Animated area chart — 60-point rolling window (2 s interval)
  • Persistence badge (💾 persistent / ⚡ ephemeral)
  • Start / Stop / Flush buttons with inline confirmation

Header actions

  • Start All / Stop All — one click for all services
  • Copy .env — copies connection strings for all running services to clipboard
  • Dark mode toggle — persisted in localStorage

Data Browser

The data browser lets you inspect stored data without connecting a client. Available for all running services via the dashboard.

Redis data browser

  • DB selector (0–15) to switch between Redis databases
  • Key table with type badge (string / hash / list / set / zset), TTL, and size
  • Key detail panel — full value display per type (hash fields, list items, set members, sorted set with scores)
  • Pattern filter (supports Redis KEYS glob patterns: user:*, session:?)

PostgreSQL data browser

  • Database selector for multi-database instances
  • Table list with row count
  • Table preview — first 100 rows with column names and types

MongoDB data browser

  • Database selector for configured databases
  • Collection list with live document count
  • Document preview — first 100 documents; BSON ObjectIds shown as hex strings, Dates as ISO strings

Log Panel

Click a service card to open its live log panel. Logs stream in real time over WebSocket.

  • 1 000-line ring buffer — scrollable, colour-coded by level (INFO / WARN / ERROR / DEBUG)
  • Text search with match highlighting
  • Auto-scroll toggle

The same logs are accessible from the CLI: lds logs <service>