GitHub
How to Write a Developer README
A walkthrough of writing one README properly, using a real project — including the two sections that do most of the work.
Most student READMEs open with installation instructions. That is the wrong order, and it is the single most common reason a good project gets skipped: nobody installs a project they do not yet care about.
A reviewer's questions arrive in a predictable sequence — what is this, can I see it working, what is it built with, how does it work, can I run it, what did you learn. Write in that order and the README does its job. Write in any other order and it does not.
This is a walkthrough of writing one, using a real example: a fixture-management tool for an amateur football club.
Start with the sentence that survives being skimmed
The first two lines are the only ones guaranteed to be read.
Weak: "A modern full-stack web application built with Next.js, TypeScript and PostgreSQL, featuring a responsive design and a clean architecture."
That is a list of technologies with no information in it. It describes several thousand student projects.
Better: "Fixture management for amateur football clubs. Committees post fixtures, players confirm availability, and everyone stops finding out about cancellations from a WhatsApp thread."
Written for someone who has never seen it, in terms of a person having a bad time. The technologies come later, in their own section, where they belong.
Put the proof directly underneath
**Live demo:** https://fixtures.example.dev
**Source:** https://github.com/you/fixtures

A GIF of the app being used is the highest-value thing in the whole file. Record one with any screen recorder, trim it to twenty or thirty seconds, and show the main flow. For a CLI tool, a terminal recording does the same job. For something that genuinely cannot be shown, three annotated screenshots.
The point is that a reviewer should not have to imagine your project working. Imagination is where projects go to be forgotten.
The problem section is where you show judgement
This is the section that separates candidates, because it is about thinking rather than typing.
Our club organised about 40 fixtures a season over WhatsApp. Cancellations got lost in the thread and players regularly turned up to games that were off. The committee tried a shared spreadsheet, but nobody opened it on a phone.
Three sentences, and they establish that you identified a real problem, understood why the existing workaround failed, and built for actual users. If the motivation was genuine annoyance, say so — it is more convincing than an invented business case, and it explains why you finished.
Name the stack, then justify one part of it
A table works well because it separates the choice from the reason:
| Layer | Choice | Why |
| --------- | ----------------- | -------------------------------------------- |
| Front end | Next.js, TypeScript | Fixture pages need to be shareable links |
| Database | PostgreSQL | Availability updates need real transactions |
| Hosting | Vercel, Neon | Free tier, deploys straight from git |
The "why" column is what matters. "Postgres because I needed transactions across three tables" is a sentence that tells a reviewer you made a decision rather than copied a starter template.
You do not need a reason for every row. One or two genuine ones beat five invented ones.
Explain the architecture briefly
Three to five sentences, plus a diagram if it helps. A few lines of ASCII is completely acceptable and often clearer than a rendered image:
Browser ──▶ Next.js route handler ──▶ Postgres
│
└──▶ Email queue (availability reminders)
The goal is to prove you understand your own system, not to write documentation for a team of twelve. If you find yourself writing four paragraphs, cut it — a reviewer who wants more detail will ask in the interview, which is a good outcome.
Now the setup instructions
Fifth, not first.
git clone https://github.com/you/fixtures.git
cd fixtures
npm install
cp .env.example .env # then fill in the values
npm run db:migrate
npm run dev
Then test them from a clean clone. Make a new folder, clone into it, and follow your own instructions exactly. This fails more often than people expect — a missing migration step, a dependency you installed globally two months ago, a config file that only exists on your machine.
Include an .env.example listing the variables with placeholder values. It tells someone what configuration is required without exposing anything.
The two sections that get read out loud in interviews
These are the ones almost nobody writes, and they are the reason to bother with a README at all.
Technical decisions. Two or three places where there was a genuine choice:
Availability stored as an event log rather than a mutable field. A player can change their mind several times before a match, and the committee wanted to see the history. Storing each change as a row means the current state is derived, which is slower to read but made the audit view trivial and eliminated a class of race condition.
What was hard. One or two specific problems. Specific is the whole game:
Fixture times were stored without timezone information. Everything worked until the clocks changed, at which point every fixture in the list shifted by an hour. I moved storage to UTC, converted at render time, and added a test that runs the fixture list across a DST boundary.
Compare that to "deployment was challenging", which is what most READMEs say and which communicates nothing. The specific version tells a reviewer you can diagnose a subtle bug, that you understood the root cause rather than patching the symptom, and that you write regression tests.
Finish with what you would change
Two or three lines:
I would put the notification logic behind a queue. Sending emails inline made the fixture-update endpoint slow and it occasionally timed out when a fixture had thirty players attached.
Being able to critique your own work is a senior habit and it is unusual on a junior portfolio. It also pre-empts the criticism a reviewer was about to make, which is a good position to be in.
The check before you call it done
- Someone outside your course can tell you what the project does from the first two lines
- There is a live link, a GIF or screenshots near the top
- The setup instructions work from a clean clone — you tried it
- No placeholder text from a template remains
- At least one real technical decision is explained, with the rejected alternative
- No secrets, keys or connection strings anywhere, including in example values
- Every link resolves
- It reads as though you wrote it
That last one matters most if you drafted with AI. Rewrite the problem, decisions and what-was-hard sections in your own words — those are the parts you will be asked about out loud, and the gap between your README's voice and your own is noticeable.
Do one, not eight
Do not try to rewrite documentation for every repository in a weekend. Write one properly on your strongest project, use it as the model, and work down the list as you have time.
A single excellent README on a pinned repository changes more than eight mediocre ones — because a reviewer reads the first one and forms their view there.
The full README template is copy-and-fill, and it is included in the free toolkit along with the project case-study template that feeds these two sections.
Want the complete 14-day system?
Developer Portfolio Builder takes you from “I need a portfolio” to application-ready in 14 days: seven modules, 30 project briefs, every template, and a scorecard to check your work.
See what’s included