Skip to content

Writing a good README in Markdown

By · Markdown · 5 min read · Updated

The README is the front page of a project. It is the first thing people see on GitHub, GitLab and npm, and often the only documentation they read before deciding whether to use, contribute to or approve a project. A good README answers a newcomer's questions in the order they ask them. This guide describes the sections that matter, how to write each one, and the Markdown details that make it render well.

Answer the first three questions immediately

A visitor wants to know, in order: what is this, is it for me, and how do I start? The top of the README should answer all three before the reader scrolls.

# invoice-parser

Extract line items, totals and tax from PDF invoices into JSON.
Works offline, supports 14 languages, no API keys required.

```bash
npm install invoice-parser
```

A one-line description in plain words beats a slogan. "Fast, flexible, modern" describes every project; "Extract line items from PDF invoices into JSON" describes yours.

The sections most projects need

1. Title and description

The project name as the only level-one heading, followed by one or two sentences on what it does and who it is for. Badges for build status, version and licence are useful, but keep them to one line; a wall of badges pushes the description below the fold.

2. Installation

The exact commands to install, in a fenced code block that can be copied. State prerequisites explicitly: language and runtime versions, system libraries, required services such as a database. "Requires Node.js 20 or later" saves an hour of confusing errors.

3. Quick start

The smallest complete example that does something useful, with the output it produces. Readers should be able to paste it and see it work within a minute. This is the most valuable part of the README and the most often missing.

4. Usage

The common tasks, each with a short heading and an example. Link to full documentation for everything else rather than reproducing the entire API in the README.

5. Configuration

Environment variables and options, ideally as a table with name, default and description. Mark which ones are required.

6. Development

How to run the project locally, run the tests and build it. For internal projects, this section may matter more than usage: it is what a new team member needs on day one.

7. Contributing, licence and support

How to report bugs, whether pull requests are welcome, where to ask questions, and the licence. Larger projects move contribution details to CONTRIBUTING.md and link to it.

Writing style

  • Lead with examples. People skim prose but read code. Show, then explain.
  • Use the second person and the imperative. "Run make test" is clearer than "Tests can be run by executing make test".
  • Keep it current. A README with outdated commands is worse than a short one. Test the quick start whenever you release.
  • Explain the why for unusual choices. If the project requires an unusual setup step, one sentence of reasoning prevents a dozen issues.

Markdown that renders well

Headings

Use one # heading for the title and ## for sections, without skipping levels. GitHub builds an automatic table of contents from headings, and screen readers use them for navigation. Use ATX-style headings with # rather than underlined Setext headings; they are easier to scan and to edit.

Code blocks

Always use fenced code blocks with a language identifier, such as ```bash, ```js or ```yaml, for syntax highlighting. Do not include the shell prompt ($) in commands people will copy, or separate it clearly from the output.

Lists and blank lines

Put a blank line before and after lists, code blocks and headings. Without it, some renderers merge a list into the preceding paragraph. Use one list marker style consistently; - is the most common.

Tables

GitHub Flavored Markdown supports tables, which are ideal for configuration options. Keep them small: tables with long cells are hard to edit in source form. Aligning the pipes makes the source readable, and a formatter can do the alignment for you.

Links and images

Use relative links to other files in the repository, like [contributing guide](CONTRIBUTING.md), so they work on forks, branches and in local clones. Give every image alt text describing what it shows. A screenshot or short GIF of the tool in action is often the most convincing element of a README, but compress it and keep it under a few megabytes.

Collapsible sections

GitHub renders HTML <details> and <summary> elements, which are handy for long output, rarely needed configuration or troubleshooting sections that would otherwise dominate the page. Leave a blank line after the <summary> line, or the Markdown inside will not be rendered:

| Option    | Default | Description                      |
| --------- | ------- | -------------------------------- |
| `--out`   | `dist`  | Output directory                 |
| `--watch` | `false` | Rebuild when source files change |

<details>
<summary>Troubleshooting: "EACCES" on install</summary>

Run the install without `sudo` and fix npm's directory permissions instead:
see the npm docs on resolving EACCES errors.

</details>

Platform differences

GitHub, GitLab, Bitbucket and npm all render Markdown slightly differently. npm, for example, does not render some GitHub-specific features, and relative image paths break on npm unless they are absolute URLs. If your package is published to a registry, check how the README looks there too. Admonition syntax such as > [!NOTE] works on GitHub but appears as a plain quote elsewhere.

Keep it consistent with a formatter

When several people edit a README, list styles, heading spacing and table alignment drift. Running a Markdown formatter keeps the source tidy and diffs small. The Markdown Formatter uses Prettier to normalise lists, headings, emphasis and blank lines and to align tables, while leaving code blocks untouched. Run it before each release, or add Prettier to your CI to do it automatically.

A quick checklist

  1. Can a stranger tell what the project does from the first two lines?
  2. Can they install it and run a working example in under five minutes?
  3. Are prerequisites and versions stated?
  4. Does every code block have a language and run as written?
  5. Do all links and images work on the platforms where the README is shown?
  6. Is it clear how to get help and how to contribute?