Riverbed CLI
A single-binary tool for local development environments that replaced a 900-line shell script.
Placeholder case study. This one has
featured: false, so it appears on/projectsbut not on the home page — useful for verifying that filter.
Problem
Onboarding a new engineer took two days, and most of it was environment setup driven by a shell script that had grown to about 900 lines over four years. It worked on the machines of the people who maintained it. It had a documented workaround list longer than most of the codebase’s actual documentation.
The failure mode that mattered was silence: the script would partially succeed, leave the environment in an undefined state, and fail later with an error that pointed nowhere near the actual cause.
Approach
Declare the desired state, do not script the steps. Configuration describes what should be true; the tool figures out how to get there and what is already satisfied.
# riverbed.yml — checked into the repo, versioned with the code it configures.
services:
postgres:
version: '16'
databases: [app_dev, app_test]
redis:
version: '7'
tools:
node: '22.15.0'
go: '1.24'
Idempotent by construction. Every operation checks current state before acting. Running the tool twice is a no-op, which means the recovery instruction for any failure is simply “run it again” — a meaningful improvement over a script where re-running could compound the damage.
Diagnose, then act. A doctor subcommand reports what is wrong and what it
would change, without changing anything. Most support requests became
self-service once people could see the diff.
One binary, no bootstrap. Written in Go and distributed as a static binary, so there is no chicken-and-egg problem where setting up the environment requires a working environment.
Outcome
- Onboarding went from two days to about 40 minutes, nearly all of it unattended download time.
- Environment-related support requests fell by roughly 85%.
- The 900-line shell script was deleted.
- Because config lives in the repo, environment changes now ship with the code that requires them instead of arriving as a message in a chat channel.
The doctor subcommand turned out to be the highest-leverage piece, which I did
not anticipate. Most of the original pain was not that setup was hard — it was
that failure was opaque.