READMEs
A README answers three questions for someone who just arrived: what is this, how do I run it, and how do I contribute? That's the job. Everything else — architecture, API reference, deployment procedures, design rationale — belongs in a linked document, because a README that tries to be complete stops being readable, and a README nobody reads means every newcomer asks the same questions in Slack.
The most common failure is not a bad README but a long one. Twelve sections deep, the setup instructions are below the fold, and the one thing a new contributor needed — the command to start the thing — is somewhere in the middle. The second most common failure is instructions that no longer work, which is worse: a wrong README costs more time than no README, because the reader trusts it and debugs their environment instead of the document.
The bar to aim for is concrete: a competent engineer who has never seen this repository can get it running in under five minutes.
TL;DR
- Answer three questions: what is this, how do I run it, how do I contribute?
- The setup commands must appear near the top and must work on a clean machine.
- One sentence at the top saying what it is — assume the reader has zero context.
- Link out for architecture, API reference, and deployment. Don't inline them.
- Test the instructions on a fresh clone, ideally in CI.
- Internal READMEs need ownership and support channel; open-source ones need license and contributing.
- Badges are useful in small numbers — build status, version, license. A wall of them is noise.
- A README that hasn't changed while the project has is probably wrong.
Quick Example
An internal service README that does its whole job in one screen:
The troubleshooting section at the bottom is worth noting: two entries, both real, both saving fifteen minutes. Every repository has two or three of these, and almost none of them are written down.
Core Concepts
The structure
The ordering matters more than the content. A reader scrolling past three paragraphs of philosophy to find npm install has already formed an opinion about the project.
Internal vs. open source
An open-source README has to sell before it explains — the reader is deciding whether to invest attention. An internal README can skip that and get straight to the operational facts, but must answer "who do I ask?" which open source answers with an issue tracker.
The five-minute test
Things this catches every time: an undocumented dependency you have installed globally, an environment variable that lives only in your shell, a step you do automatically and forgot to write down, and a version requirement that's newer than what's stated.
Automating it in CI is straightforward and worth it:
Now the README's instructions break the build when they stop being true, which is the only reliable way to keep them accurate.
Badges
Three to five, all conveying real information: build status, published version, license, and perhaps coverage or bundle size. A row of twelve badges is decoration that pushes the setup instructions below the fold, and readers stop parsing them after the third.
The companion files
A README shouldn't contain everything, and these are where the rest goes:
SECURITY.md is the one most often missing on projects that need it. Without it, a researcher who finds a vulnerability either files a public issue or gives up.
Best Practices
Put the setup commands above the fold
Everything a reader needs to run the project should be visible without scrolling past a screen. Move the motivation, the philosophy, and the feature list below it, or into a linked document.
State what it is in one sentence, without jargon
"A distributed event-sourced CQRS platform" tells a newcomer nothing. "Handles subscription billing and invoicing for the customer platform" tells them everything they need to decide whether they're in the right repository.
Make every command copy-pasteable
Complete commands with no placeholders. Where a value must vary, provide the command that produces it. A reader who has to figure out what <your-api-key> should be has been handed homework.
Test the instructions in CI
The single most effective practice here. Instructions verified by a machine on every commit can't silently rot, and the failure surfaces as a build break rather than as a new hire's lost afternoon.
Include a troubleshooting section
Two or three entries for the errors people actually hit — the port conflict, the stale Docker volume, the Node version mismatch. This section has the highest ratio of value to effort in the entire document, and it's built by writing down the questions people ask.
Link out rather than inlining
Architecture, API reference, deployment, and design rationale each belong in their own document. The README's job is to be the index. A 2,000-line README is a sign that several documents are trapped inside one.
Say who owns it
For internal repositories: the team, the Slack channel, and the on-call rotation. "Who do I ask about this?" is the second question every newcomer has, and leaving it unanswered wastes far more time than writing one line.
Update it in the same PR
Changing the setup process, adding a required environment variable, or bumping a runtime version means changing the README in the same change. See Docs-as-Code.
Common Mistakes
Setup instructions buried or missing
Untested instructions
FAQ
How long should a README be?
One screen for the essentials, and up to a few hundred lines total if the extras earn their place. Past that, you're writing documentation that should live in docs/. A useful test: if someone has to use ctrl-F to find the run command, it's too long.
Should the README include API documentation?
Only for a small library where the API is the project — a utility with three functions is fine documenting them inline. For anything larger, link to generated reference. Hand-written API tables in a README are guaranteed to drift, and they push the setup instructions down. See API Documentation.
What about a demo or screenshot?
Essential for anything visual and open source — a screenshot or a short GIF communicates in two seconds what a paragraph doesn't. Keep the file small (a GIF over a megabyte is a poor first impression) and put it immediately after the description. For internal backend services, skip it.
Do READMEs matter for internal repositories?
More than for open source, arguably. An internal repository has a captive audience who must work with it, and every missing piece of setup information is paid for repeatedly by every new team member. The ownership line alone saves more time than most of what's in it.
Should AI write our READMEs?
It's good at the first draft and at structure, particularly for a codebase it can read — it will produce a reasonable inventory of what the project does and a plausible setup section. What it can't do is know that step 3 fails on a fresh machine, or that everyone hits the same Docker volume issue. Generate the draft, then run the five-minute test yourself and add the troubleshooting section from real experience.
What goes in README vs. CONTRIBUTING?
README: what it is, how to run it, and where the documentation is — aimed at anyone who lands on the repository. CONTRIBUTING: development environment detail, coding conventions, testing requirements, PR and review process, release procedure — aimed at people who are going to change the code. When the README's contributing section grows past a paragraph, move it.
Related Topics
- Technical Writing — The broader documentation practice
- Docs-as-Code — Keeping the README verified in CI
- Release Notes & Changelogs — The companion history file
- Contributing to Open Source — The reader's perspective
- Open Source Licensing — What the LICENSE file needs to be
- Architecture Decision Records — Where the "why" lives
- Runbooks — Operational procedures the README links to
- Onboarding Engineers — Where READMEs are stress-tested