Ubin.io All Articles
Engineering Culture

Your Onboarding Docs Are a Time Bomb: Fixing the Local Dev Setup Problem

By Ubin.io Engineering Culture
Your Onboarding Docs Are a Time Bomb: Fixing the Local Dev Setup Problem

Somewhere in your company's Confluence, Notion, or GitHub wiki, there's a README titled something like "Getting Started" or "Local Development Setup." It was written by someone who no longer works there, on a machine that no longer exists, for a version of the codebase that has since changed in ways nobody fully tracked.

And every few weeks, a new engineer sits down, follows those instructions, and spends the next three to five days in a quiet hell of mysterious errors, Slack messages to people who don't know the answer either, and growing suspicion that they made a mistake accepting the offer.

This isn't a fringe problem. It's endemic to growing engineering organizations, and it's one of the most expensive invisible costs in software development. Not because the setup time itself is so long — though three days is a lot — but because of what it signals to the person experiencing it. A broken onboarding experience tells new engineers that the team doesn't value their time, that the codebase is poorly maintained, and that tribal knowledge is the real currency here. Some of those engineers will push through. Some will quietly update their LinkedIn.

Why Setup Docs Decay So Fast

The half-life of a local development guide is shorter than most people realize. A few reasons:

The person who wrote it optimized for their own machine. Setup docs written by experienced engineers are usually written from memory, which means they skip the parts that feel obvious — and those parts are exactly where new engineers get stuck. The doc assumes Homebrew is already installed. It assumes you know what nvm is. It assumes your shell is configured a certain way. None of those assumptions are documented, because to the author, they're just the environment.

Services get added faster than docs get updated. The app now depends on Redis, but the setup guide predates Redis. A third-party API integration was added six months ago, and the API key you need is... somewhere. Someone's brain, probably. The codebase grows, the dependencies multiply, and the documentation stays frozen at whatever state it was in when someone last had time to write it.

OS-specific gotchas are everywhere and nobody tracks them. The difference between running this stack on an M2 Mac versus an Intel Mac versus a Linux machine can be significant — different architecture, different package manager behavior, different file system case sensitivity. If your team is even slightly heterogeneous in hardware, your docs are almost certainly wrong for someone.

The Real Audit Checklist

Before you can fix your local dev setup, you have to understand what's actually broken. Here's how to do a real audit rather than a surface-level review:

Run through the docs yourself on a clean machine. Not a machine where the stack is already set up — a clean one. Use a VM, a spare laptop, or a new cloud instance. Follow every step exactly as written. Note every place where you had to do something the docs didn't mention, every error you had to Google, every assumption that turned out to be wrong. This exercise is humbling and essential.

Interview your last three or four new hires. Ask them specifically: what broke? What took the longest? What did you have to ask someone for that wasn't documented? What do you wish you'd known on day one? Their answers are gold. They experienced the current state of your docs without the context that makes experienced engineers blind to the gaps.

Map every external dependency explicitly. Sit down and list every service, API, database, queue, or external system the application touches — even in development mode. For each one, ask: does the setup doc explain how to get this running locally? Is there a local alternative (Docker Compose service, mock, emulator)? Where do credentials come from? If any of these questions don't have clear answers in your docs, you've found a gap.

Check for undocumented environment variables. Run grep -r 'process.env' . or the equivalent for your stack and compare against what's in your .env.example. The difference is a list of things your app needs that a new engineer won't know about. Every undocumented env var is a mystery error waiting to happen.

Building for Reproducibility, Not Just Accuracy

The goal isn't docs that are accurate — accuracy decays. The goal is an environment setup that's reproducible by design, so that the docs almost don't matter.

Containerize your local dev dependencies. Docker Compose for your database, cache, queue, and any supporting services means "install PostgreSQL" stops being a platform-specific adventure and becomes a single command. This doesn't solve everything, but it eliminates a whole category of "it works on my machine" problems before they start.

Use a .env.example that's actually maintained. Every required environment variable should live in .env.example with a comment explaining what it's for and how to get the value. This file should be part of your PR review process — if you add an env var, you update the example. No exceptions.

Consider a setup script. A shell script (or Makefile target) that runs through the setup steps programmatically is better than a doc for a few reasons: it's testable, it's repeatable, and it fails loudly when something is wrong rather than silently producing a broken environment. Tools like mise (formerly rtx) or asdf can help standardize language version management across the team without everyone having to configure it manually.

Document the "why" alongside the "what." New engineers don't just need to know what commands to run — they need enough context to debug when something goes wrong. A note that says "this service needs to be running before you start the app because X" is far more useful than just listing the command, because it helps the person understand the system rather than just execute a script they don't understand.

The Ownership Problem

None of this works without someone owning it. Local dev setup is the kind of thing that everyone agrees is important and nobody prioritizes, because the people who feel the pain most acutely (new hires) are also the people with the least organizational capital to fix it.

Assign ownership explicitly. Whether that's a platform team, a senior engineer on a rotating basis, or whoever is running the next onboarding cohort — someone needs to be responsible for keeping the setup experience current. Treat it like production infrastructure: it has an owner, it gets reviewed, it gets updated when things change.

And measure it. Track how long it takes new engineers to get from "laptop received" to "first PR merged." That number should go down over time. If it's not, something is wrong.

The Signal It Sends

A local development experience that works on day one isn't just a convenience. It's a statement about what kind of team you are. It says that you value other people's time. That you think carefully about the experience of working here, not just the experience of using what you build. That operational excellence extends all the way to the beginning of the developer journey.

That's the kind of signal that retains engineers and attracts the ones you actually want to hire. It's worth the investment.