How to write a good README: a structure that explains your project in 30 seconds
What to put in a README and in what order: a one-line pitch, a visual, a working quick start, configuration, project structure, plus a template.
DocumentationBy the Codeshot team6 min read
Quick answer: A good README answers a visitor's questions in the order they ask them: what is this, is it for me, what does it look like, how do I try it, how do I use it properly, how is it organized, and can I trust it. Lead with a one-sentence description and a visual, follow with a copy-pasteable quick start, and move everything else into clearly titled sections.
A visitor lands on your repository from a search result, a link in a thread or a dependency list. Within about half a minute they decide whether to keep reading, try the project or close the tab. The README is the whole pitch, and most of them bury the answer under badges, history and installation edge cases.
This guide lays out a README structure based on what visitors need, explains each section with examples, and ends with a template you can copy.
The seven questions a README must answer
- What is this? A one-line description.
- Is it for me? Who it is for and what problem it solves.
- What does it look like? A screenshot, terminal image or example output.
- How do I try it? A quick start that works on the first attempt.
- How do I use it for real? Configuration, common tasks and links to full docs.
- How is it organized? The project layout, for contributors.
- Can I trust it? License, status, maintenance and support.
Structure the README around these questions, in this order, and most of the hard decisions make themselves.
Write a one-line description that says what it does
Directly under the project name, write one sentence that states what the project does and for whom. Skip the adjectives every project claims and lead with the outcome.
| Weak | Strong |
|---|---|
| A next-generation, highly extensible framework. | A CLI that turns a folder of Markdown files into a static documentation site. |
| Blazing-fast utilities for modern apps. | Date formatting for JavaScript in 2 kB, with time zone support. |
Follow it with two or three sentences on the problem it solves and who it is for. If there are well-known alternatives, say briefly how yours differs — visitors are usually comparing.
Show it before you explain it
Put a visual near the top. It answers "what does it look like?" faster than any paragraph.
- An app or UI: a screenshot of the main screen, at default settings.
- A command-line tool: an image of a real command and its output, or a short recording.
- A library: a short code example and its result.
Keep it honest: show the real product doing exactly what the one-liner promises. On GitHub you can provide light and dark versions of an image with the HTML <picture> element and the prefers-color-scheme media query, so the image matches each reader's theme.
Make the quick start work on the first try
The quick start is the most valuable section — and the one most often broken. It should take someone from nothing to a working result in as few steps as possible:
npm install -g mdsite
mdsite init my-docs
cd my-docs
mdsite dev # → http://localhost:4000
Rules that keep it working:
- Use text code blocks for commands so they can be copied. A terminal image is a good companion, never a replacement.
- State prerequisites with versions, such as "Node.js 20 or later".
- Show what success looks like — the URL, the output line or the screenshot readers should see.
- Test it on a clean machine or container before each release. Your laptop already has the step you forgot.
If installation differs by platform, give the most common path in the README and link to a full installation page for the rest.
Document configuration in a table
If your project reads environment variables or a config file, document every option: its name, whether it is required, its default and what it does. A committed .env.example file plus a table in the README is the clearest combination.
| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 4000 |
Port for the development server |
SITE_URL |
Yes | — | Canonical URL used in links and the sitemap |
ANALYTICS_ID |
No | — | Enables analytics when set |
Never use real values in examples, even for services that seem harmless. See how to redact secrets in screenshots for safe placeholder conventions.
Cover the common tasks, then link to the docs
Show the three to five things most people come to do, each with a short example. Link to full documentation for everything else.
A README that tries to be the complete manual becomes too long to scan; one that just says "see the docs" forces an extra click before the visitor is convinced. Common tasks in the README, the reference elsewhere, is the right balance.
Explain the project structure for contributors
A short, annotated tree of the repository answers "where does this live?" before anyone has to ask:
mdsite/
├── src/
│ ├── cli/ # command parsing and entry points
│ ├── build/ # Markdown → HTML pipeline
│ └── server/ # dev server with live reload
├── templates/ # starter projects used by `mdsite init`
├── tests/
└── docs/
- Show two or three levels at most.
- Annotate only directories whose purpose is not obvious from the name.
- Leave out generated folders such as
node_modules,distand.git. - Update the tree when you reorganize.
tree -L 2 -I 'node_modules|dist' generates a starting point on macOS and Linux. For architecture or data-flow diagrams, GitHub renders Mermaid code blocks directly in Markdown.
Add trust signals
Visitors deciding whether to depend on your project look for:
- License: name it and link the
LICENSEfile. - Status: stable, beta or experimental — and whether it is actively maintained.
- Support: where to ask questions, and how to report security issues privately (a
SECURITY.mdfile). - Contributing: a link to
CONTRIBUTING.mdand the command to run the tests.
Badges are fine in moderation. A build status, the latest version and the license are informative; a wall of twenty badges pushes the actual content below the fold.
Common README mistakes
- Starting with the project's history instead of what it does.
- A quick start that assumes tools or accounts the reader does not have.
- Screenshots from three versions ago.
- Installation instructions for every platform, in full, before the first example.
- No license — without one, others have no legal permission to use, modify or share the code.
A README template you can copy
# project-name
One sentence: what it does and for whom.
Two or three sentences on the problem it solves and how it differs from alternatives.

## Quick start
```sh
install command
first command
```
## Usage
### Common task one
### Common task two
## Configuration
| Variable | Required | Default | Description |
| --- | --- | --- | --- |
## Project structure
```text
annotated tree
```
## Contributing
## License
Create the visuals quickly
For the "show it" and structure sections, the terminal session tool turns an install-build-run sequence into one clean image, the file tree image generator styles your repository layout, the ASCII tree generator handles other hierarchies such as module graphs or decision flows, and the environment variables tool presents your .env.example. Keep the copyable text right next to every image — see how to write alt text for code images.
Frequently asked questions
What should be included in a README file?
A one-line description, a short explanation of who it is for, a visual, a quick start, configuration, common usage examples, the project structure for contributors, and the license, status and support information.
How long should a README be?
Long enough to get a new user to a working result and show the common tasks — usually a few screens. Move complete reference material into separate documentation and link to it.
Should a README include screenshots?
Yes, for anything with visible output. A screenshot or terminal image near the top shows what the project does faster than text. Keep commands as copyable text as well.
What is the best format for a README?
Markdown (README.md) is the standard on GitHub, GitLab and most package registries, which render it automatically on the project page.