Your fans stay off
No VM, no reserved slab of RAM. At rest, your entire backend is one ~15 MB daemon; engines boot on first connection and reap to zero when idle. The machine’s power goes to your build, not to virtualization.
# doze.hcl — your whole local backend, declaredpostgres "app" { version = 18 }valkey "cache" { version = 9 }
s3 "uploads" { port = 9000 versioning = true}$ brew install doze-dev/tap/doze$ doze up ✓ app (postgres 18) ready ✓ cache (valkey 9) ready ✓ uploads (s3) ready$ doze status ● app postgres 18 active 127.0.0.1:5432 42.5M ○ cache valkey 9 asleep — — # zero cost until usedContainerization is great — for shipping. For development, convenience made it acceptable to be resource-hungry: a VM holding half your RAM all day, the whole stack running while you edit one service, remote-k8s dev loops with latency where your inner loop should be. doze reverses that bargain.
Your fans stay off
No VM, no reserved slab of RAM. At rest, your entire backend is one ~15 MB daemon; engines boot on first connection and reap to zero when idle. The machine’s power goes to your build, not to virtualization.
Your debugger just attaches
Everything is a native process on your kernel. dlv/lldb attach
directly, ps/lsof/Instruments see the real engine, core dumps land on
your disk. No boundary, no port-forward mazes, no bind-mount heisenbugs.
The debugger story →
Real engines, exactly
The actual upstream Postgres 18, the actual Valkey — not images, not
emulations. Every extension and wire feature behaves like production,
pinned to the byte in doze.lock for your whole team.
Modern apps aren’t one process; they’re a mesh of them. doze runs your
services too — declare an API, a worker, an auth service as process blocks
and doze starts them in dependency order, waits until each is actually ready,
and wires them to each other and to their data. It’s a local microservices
orchestrator that happens to also run your databases.
And you can keep the data elsewhere: point a service’s env at a remote or
shared Postgres and doze becomes a pure process runner — your code local and
debuggable, your data wherever it already lives.
process "api" { cwd = "../api" command = "npm run dev" port = 8080 env = { DATABASE_URL = postgres.db.url } # or a remote URL — doze doesn't mind health { http = "http://localhost:8080/health"; retries = 30 }}Use doze
Install it, declare your backend, get on with your app. Install → · Getting started → · Coming from docker-compose →
Understand it
The full case: native processes vs containers, why HCL, and an honest look at the alternatives. Why doze →
Build a module
Every engine is a plugin, and third-party modules are exactly as capable as official ones. Start from a working template. Author guide →
Run a registry
Modules arrive signed, key-pinned, and locked — and the registry is static files you can host yourself, air-gapped included. Operator guide → · Browse modules →