
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Run Zero locally with zero native dependencies. No Postgres install, no SQLite compilation, no Docker.
bunx orez
oreZ makes Zero work on PGlite (Postgres in WASM) and bedrock-sqlite (SQLite in WASM), bundled together so local development is as simple as bun install && bunx orez.
This is a development tool only. Not suitable for production.
orez pg_dump for backups.bunx orez
What oreZ handles automatically:
pg_notify triggers, with adaptive polling fallback (20ms catching up, 500ms idle)pg_dump/pg_restore with COPY→INSERT conversion, auto-coordinates with zero-cachebunx orez
--pg-port=6434 postgresql proxy port
--zero-port=5849 zero-cache port
--data-dir=.orez data directory
--migrations=DIR migrations directory (skipped if not set)
--seed=FILE seed file path
--pg-user=user postgresql user
--pg-password=password postgresql password
--skip-zero-cache run pglite + proxy only, skip zero-cache
--log-level=warn error, warn, info, debug
--s3 also start a local s3-compatible server
--s3-port=9200 s3 server port
--force-wasm-sqlite force wasm sqlite even if native is available
--disable-wasm-sqlite force native sqlite (fail if not available)
--on-db-ready=CMD command to run after db+proxy ready, before zero-cache
--on-healthy=CMD command to run once all services healthy
--disable-admin disable admin dashboard
--admin-port=6477 admin dashboard port (default: 6477)
Ports auto-increment if already in use.
Create an orez.config.ts (or .js / .mjs) in your project root:
import { defineConfig } from 'orez'
export default defineConfig({
pgPort: 5433,
zeroPort: 4848,
adminPort: 6477,
migrations: './db/migrations',
seed: './db/seed.sql',
s3: true,
s3Port: 9300,
logLevel: 'info',
onHealthy: 'echo "ready!"',
})
All options mirror the CLI flags in camelCase. CLI flags override config file values, so orez --pg-port 6000 wins over pgPort: 5433 in the config.
| Config key | CLI flag | Default |
|---|---|---|
pgPort | --pg-port | 6434 |
zeroPort | --zero-port | 5849 |
adminPort | --admin-port | 6477 |
s3Port | --s3-port | 9200 |
dataDir | --data-dir | .orez |
pgUser | --pg-user | user |
pgPassword | --pg-password | password |
migrations | --migrations | — |
seed | --seed | — |
skipZeroCache | --skip-zero-cache | false |
s3 | --s3 | false |
disableAdmin | --disable-admin | false |
disableWasmSqlite | --disable-wasm-sqlite | false |
forceWasmSqlite | --force-wasm-sqlite | false |
noWorkerThreads | --no-worker-threads | false |
singleDb | --single-db | false |
logLevel | --log-level | warn |
onDbReady | --on-db-ready | — |
onHealthy | --on-healthy | — |
.ts config files require Node 22.6+ or Bun. Use .js/.mjs on older Node versions.
Enabled by default at http://localhost:6477.
Logs are also written to separate files in your data directory: zero.log, proxy.log, pglite.log, etc.
bunx orez --disable-admin # disable dashboard
bun install orez
import { startZeroLite } from 'orez'
const { config, stop, db, instances } = await startZeroLite({
pgPort: 6434,
zeroPort: 5849,
migrationsDir: 'src/database/migrations',
seedFile: 'src/database/seed.sql',
adminPort: 6477, // set to 0 to disable
})
// your app connects to zero-cache at localhost:5849
// database is at postgresql://user:password@localhost:6434/postgres
// db is the postgres PGlite instance (for direct queries)
// instances has all three: { postgres, cvr, cdb }
await stop()
All options are optional with sensible defaults.
| Hook | CLI | Programmatic | When |
|---|---|---|---|
| on-db-ready | --on-db-ready=CMD | onDbReady: 'CMD' or onDbReady: fn | after db + proxy ready, before zero |
| on-healthy | --on-healthy=CMD | onHealthy: 'CMD' or onHealthy: fn | after all services ready |
Shell commands receive env vars: DATABASE_URL, OREZ_PG_PORT, OREZ_ZERO_PORT. Change tracking triggers are re-installed after onDbReady.
import { orezPlugin } from 'orez/vite'
export default {
plugins: [
orezPlugin({
pgPort: 6434,
zeroPort: 5849,
migrationsDir: 'src/database/migrations',
onDbReady: () => console.log('db ready'),
onHealthy: () => console.log('all services healthy'),
}),
],
}
Starts oreZ when vite dev starts, stops on close. Supports all startZeroLite options plus s3 and s3Port.
Dump and restore your local database — no native Postgres install needed.
bunx orez pg_dump > backup.sql
bunx orez pg_dump --output backup.sql
bunx orez pg_restore backup.sql
bunx orez pg_restore backup.sql --clean # drop public schema first
When oreZ is running, restore through the wire protocol:
bunx orez pg_restore backup.sql --pg-port 6434
This automatically:
The --direct flag forces direct PGlite access, skipping wire protocol.
pg_stat_statements, pg_buffercache, pg_cron etc. silently skippedCREATE SCHEMA → IF NOT EXISTS, CREATE FUNCTION → OR REPLACE$$ and $tag$ in function bodiesStandard Postgres tools (pg_dump, pg_restore, psql) also work against the running proxy.
All ZERO_* env vars are forwarded to zero-cache. oreZ provides defaults:
| Variable | Default | Overridable |
|---|---|---|
NODE_ENV | development | yes |
ZERO_LOG_LEVEL | from --log-level | yes |
ZERO_NUM_SYNC_WORKERS | 1 | yes |
ZERO_ENABLE_QUERY_PLANNER | false | yes |
ZERO_UPSTREAM_DB | (managed) | no |
ZERO_CVR_DB | (managed) | no |
ZERO_CHANGE_DB | (managed) | no |
ZERO_REPLICA_FILE | (managed) | no |
ZERO_PORT | (managed) | no |
Common vars you might set:
ZERO_MUTATE_URL=http://localhost:3000/api/zero/push
ZERO_QUERY_URL=http://localhost:3000/api/zero/pull
Since Zero apps often need file uploads and MinIO requires Docker:
bunx orez --s3 # with orez
bunx orez s3 # standalone
import { startS3Local } from 'orez/s3'
const server = await startS3Local({ port: 9200, dataDir: '.orez' })
Handles GET, PUT, DELETE, HEAD with CORS. Files stored on disk. No multipart, no ACLs, no versioning.
oreZ runs three components:
zero-cache expects three databases with independent transaction contexts. PGlite is single-session — all connections share one session. Without isolation, CVR transactions get corrupted by postgres queries (ConcurrentModificationException).
| Connection database | PGlite instance | Data directory |
|---|---|---|
postgres | postgres | pgdata-postgres |
zero_cvr | cvr | pgdata-cvr |
zero_cdb | cdb | pgdata-cdb |
PGlite doesn't support logical replication, so oreZ fakes it:
_orez._zero_changesChange notifications use pg_notify for real-time sync. Polling (20ms/500ms adaptive) is fallback only.
zero-cache needs SQLite via @rocicorp/zero-sqlite3 (native C addon). oreZ intercepts this at runtime using Node's ESM loader hooks, redirecting to bedrock-sqlite — SQLite's bedrock branch compiled to WASM with BEGIN CONCURRENT and WAL2.
The shim also polyfills the better-sqlite3 API surface zero-cache expects.
For --disable-wasm-sqlite, bootstrap the native addon first:
bun run native:bootstrap
oreZ stores replication state in the _orez schema (survives pg_restore --clean):
_orez._zero_changes — change log for replication_orez._zero_replication_slots — slot tracking_orez._zero_watermark — LSN sequenceThe proxy intercepts and rewrites to make PGlite look like real Postgres:
| Query/Command | What oreZ does |
|---|---|
version() | Returns PostgreSQL 17.4 on x86_64-pc-linux-gnu... |
current_setting('wal_level') | Returns logical |
IDENTIFY_SYSTEM | Returns fake system ID and timeline |
CREATE_REPLICATION_SLOT | Persists to local table, returns valid LSN |
START_REPLICATION | Streams changes as pgoutput binary |
pg_replication_slots | Redirects to local tracking table |
READ ONLY / ISOLATION LEVEL | Stripped (single-session) |
Things that don't "just work" when replacing Postgres with PGlite and native SQLite with WASM:
PGlite is single-session — if pg_restore sets search_path = '', every subsequent connection inherits it. On disconnect, oreZ resets search_path, statement_timeout, lock_timeout, and rolls back open transactions.
ZERO_ENABLE_QUERY_PLANNER=false because it relies on SQLite scan statistics that cause infinite loops in WASM.
Columns with tsvector, tsquery, USER-DEFINED types are filtered from replication messages.
If ZERO_APP_PUBLICATIONS is set, only tables in that publication get change-tracking triggers.
After restore, triggers whose backing functions don't exist are dropped (happens with filtered pg_dump).
bun run test # orez tests
bun run test:integration:native # native sqlite integration
cd sqlite-wasm && bunx vitest run # bedrock-sqlite tests
src/
cli-entry.ts auto heap sizing wrapper
cli.ts cli with citty
index.ts main entry, orchestrates startup
config.ts configuration types and defaults
load-config.ts orez.config.ts file loader
log.ts colored log prefixes, log files
mutex.ts serializing pglite access
port.ts auto port finding
pg-proxy.ts postgresql wire protocol proxy
pglite-manager.ts multi-instance pglite, migrations
s3-local.ts local s3 server (orez/s3)
vite-plugin.ts vite plugin (orez/vite)
admin/
server.ts admin dashboard backend
ui.ts admin dashboard frontend
log-store.ts log aggregation
http-proxy.ts http request logging
replication/
handler.ts replication state machine, adaptive polling
pgoutput-encoder.ts binary pgoutput encoder
change-tracker.ts trigger installation, change purging
integration/
*.test.ts end-to-end tests
sqlite-wasm/
Makefile emscripten build
native/api.js better-sqlite3 compatible API
native/vfs.c custom VFS with SHM for WAL2
MIT
FAQs
PGlite-powered zero-sync development backend. No Docker required.
We found that orez demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.