Skip to content

Alternatives, honestly

Tools earn trust by being honest about their neighbors. Here’s the landscape as we see it — including when you should not pick doze.

Best atReach for it whendoze’s edge over it
docker-composeDeclaring multi-service stacks portablyYour stack must mirror production containers exactlyNative processes (debuggers, no VM tax), lazy boot/reap, pinned real binaries, typed config
TestcontainersEphemeral per-test services in codeTests must own service lifecycle programmatically, per languageOne shared declarative stack for dev and tests; instant warm boots; no Docker daemon required
LocalStackBroad AWS API surface in one boxYou need many AWS services (Lambda, DynamoDB, …)Real engines for data stores; S3/SQS/SNS in pure Go, ~instant, no Docker/JVM/Python
Nix / devenv / FloxReproducible toolchains & environmentsYou want the whole environment (compilers, tools) pinnedRadically smaller learning curve; services that sleep; one lockfile scoped to backing services
Tilt / SkaffoldDev loops on KubernetesYour inner loop is genuinely k8sNot being Kubernetes for a laptop CRUD app
brew services / systemdSystem-global daemonsOne global Postgres forever is fine for youPer-project versions & data, no port fights, no always-on drain, a lockfile

docker-compose is the incumbent and a fine one: one file, docker compose up, portable anywhere Docker runs. Choose it when dev/prod container parity is the priority — when the container is the artifact you ship. Its costs are the VM on Mac/Windows (RAM held all day, bind-mount I/O, emulation for stray amd64-only images), the always-on whole-stack model, and YAML with string conventions where references should be. If your compose file is mostly “a postgres, a redis, a bucket” — the common case — doze replaces it with less machinery than it took to keep Docker Desktop updated. There’s a mental-model mapping for making the move.

Testcontainers is excellent at what it actually is: a testing library that gives each suite programmatic, throwaway containers. Choose it when tests must create bespoke topologies at runtime. As a dev environment it’s the wrong shape — nothing to psql into between runs, per-language APIs, container startup in every suite. doze inverts it: one declared stack, always a connection away, warm across runs (doze run -- go test ./...), shared with your editor and your teammates via two committed files. Many teams run doze for dev + CI services and keep Testcontainers for the exotic per-test cases.

LocalStack has admirable breadth — dozens of AWS APIs, one endpoint. Choose it when your app leans on services doze doesn’t provide (DynamoDB, Lambda, Step Functions). Its weight is the tradeoff: a ~1.2 GB image, Python + JVM inside Docker, and reimplemented APIs whose fidelity you verify against a coverage matrix. doze covers the three services most local dev actually touches — S3, SQS, SNS — as built-in pure-Go engines that boot in milliseconds, and runs real binaries for everything stateful.

Nix (and devenv, Flox) solves a bigger problem than doze does: the entire environment, hermetically. If your team already speaks Nix, services.postgres in devenv is genuinely good, and doze won’t out-reproduce it. The honest differences: the learning cliff (Nix is a language, an ecosystem, and a worldview), and services that are supervised-while-the-shell-lives rather than doze’s boot-on-connect/sleep-when-idle. doze is the 90% of the value for 2% of the onboarding.

Tilt/Skaffold answer “how do I develop on Kubernetes” — if that’s your question, doze isn’t. doze’s bet is that for most application work, Kubernetes on a laptop is complexity imported from production for no local benefit.

brew services (or systemd units) is the zero-tooling answer and the one doze most sympathizes with — it’s also native processes! What it lacks is everything around the process: per-project versions (one global 5432), pinning (whatever brew last upgraded to), scoped data dirs, idle shutdown, and a declarative file your teammate can clone. doze is brew-services with the missing management layer.

Plainly: production (single instances, no HA, idle reaping — by design); Windows without WSL2; apps needing AWS beyond S3/SQS/SNS (pair doze with LocalStack, or wait for modules); teams whose dev loop is contractually k8s. And if your whole company happily runs Nix — carry on; you have our respect.