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.
@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
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Whether to start this service on lds start |
port | number | varies | TCP port. Must not conflict with other services or running databases. |
persistence | boolean | false | Persist data to disk. Requires data_dir. |
data_dir | string | — | Directory for persistent data. Created automatically if missing. |
password | string | "" | Empty string = no authentication required. |
databases | string[] | ["postgres"] | PostgreSQL only. List of database names to initialise. |
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
| Flag | Description |
|---|---|
--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
| Code | Meaning |
|---|---|
0 | Success |
1 | General error (service failed, network error, etc.) |
2 | Config 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
| Category | Commands |
|---|---|
| Strings | GET SET DEL EXISTS MGET MSET INCR DECR INCRBY DECRBY INCRBYFLOAT APPEND STRLEN GETSET SETNX SETEX PSETEX GETEX GETDEL SETRANGE GETRANGE |
| Hashes | HGET HSET HDEL HEXISTS HGETALL HKEYS HVALS HLEN HMGET HMSET HINCRBY HINCRBYFLOAT HSETNX HRANDFIELD |
| Lists | LPUSH RPUSH LPOP RPOP LLEN LRANGE LINDEX LSET LINSERT LREM LTRIM LMOVE LPOS |
| Sets | SADD SREM SISMEMBER SMISMEMBER SMEMBERS SCARD SUNION SINTER SDIFF SUNIONSTORE SINTERSTORE SDIFFSTORE SRANDMEMBER SPOP SMOVE |
| Sorted Sets | ZADD ZREM ZSCORE ZCARD ZRANK ZREVRANK ZINCRBY ZRANGE ZREVRANGE ZRANGEBYSCORE ZREVRANGEBYSCORE ZCOUNT ZPOPMIN ZPOPMAX ZRANDMEMBER ZUNIONSTORE ZINTERSTORE |
| TTL | EXPIRE PEXPIRE EXPIREAT PEXPIREAT TTL PTTL PERSIST |
| Pub/Sub | SUBSCRIBE UNSUBSCRIBE PUBLISH PSUBSCRIBE PUNSUBSCRIBE |
| Server | PING 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
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
| Config | Auth method | Connection |
|---|---|---|
password: "" | Trust (no password) | postgresql://postgres@127.0.0.1:5432/db |
password: "secret" | MD5 | postgresql://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
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.
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.
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
| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable / disable the emulator. |
port | number | 27017 | TCP port to bind on 127.0.0.1. |
persistence | boolean | false | If true, uses WiredTiger engine with data_dir for durable storage. |
data_dir | string | — | Directory for persistent data. Required when persistence: true. |
databases | string[] | ["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
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
KEYSglob 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>