All posts

How to Write a README.md That Developers Actually Read

A practical guide to writing README files that get read. Covers structure, formatting, code examples, Mermaid diagrams, and templates for open-source projects and CLI tools.

A good README is the difference between a project that gets used and a project that gets ignored. I've read hundreds of READMEs — as a user evaluating tools, as a reviewer looking at pull requests, as a maintainer of my own projects. The gap between the good ones and the bad ones usually isn't technical. It's structural.

This is what I've learned.


Why READMEs Matter More Than You Think

When someone lands on your repository for the first time, the README is the first thing they see. They're asking four questions:

  1. What does this do?
  2. How do I install it?
  3. How do I use it?
  4. Should I trust it?

If your README can't answer all four in under 60 seconds of reading, you've lost them. Most developers have a dozen browser tabs open and a task list that's already too long. Give them a reason to keep reading.

The README is also your project's marketing copy — even for internal tools. It sets the tone, communicates quality, and signals whether the project is actively maintained. A well-formatted README with working code examples communicates "this person knows what they're doing." A blank README or a README with broken code examples communicates the opposite.


The Anatomy of a Great README

Here's the structure that works:

1. Project Name and Tagline

# my-project

A fast, minimal CLI tool for converting markdown files to HTML.

One line. What it does. Don't write "this project is..." or "my-project is a tool that helps you...". Lead with the verb: "Converts markdown to HTML." "Monitors disk usage across servers." "Validates configuration files against JSON Schema."

2. Badges (Optional but Worth It)

![npm version](https://img.shields.io/npm/v/my-project)
![CI](https://github.com/user/my-project/actions/workflows/ci.yml/badge.svg)
![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)

Badges give instant signals: is this actively maintained? Does CI pass? What license? Keep them to 3-4 meaningful ones. A row of 12 badges is noise.

3. Quick Install

## Installation

```bash
npm install my-project

The install command should be the very first code block. If installation is more complex (requires environment variables, depends on other services), put the quick install first and link to a more detailed setup guide below.

### 4. Quick Start / Usage Example

This is the most important section and the one most READMEs get wrong. Show the simplest possible example that demonstrates value. Working code. Copy-pasteable. Output included.

```markdown
## Usage

```javascript
import { convert } from 'my-project'

const html = convert('# Hello world')
console.log(html)
// => '<h1>Hello world</h1>'

If your API is bigger, pick the 20% of usage that covers 80% of use cases. Everything else goes in a docs section or link.

### 5. Architecture Diagram (for Complex Projects)

For non-trivial projects, a visual of how components fit together is worth more than paragraphs of explanation. Mermaid diagrams are ideal here — they live in the README, render on GitHub, and don't require external image files.

````markdown
## Architecture

```mermaid
flowchart LR
  CLI[CLI Tool] --> Parser[Markdown Parser]
  Parser --> AST[AST]
  AST --> Renderer[HTML Renderer]
  Renderer --> Output[HTML Output]

This renders as an actual diagram on GitHub, in OpenMark, and in any Mermaid-aware viewer. It updates when you update the markdown — no need to export a new PNG.

### 6. API Reference (if applicable)

For libraries and packages, document the public API. Tables work well here:

```markdown
## API

### `convert(markdown, options?)`

Converts a markdown string to HTML.

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| markdown | string | — | The markdown source |
| options.sanitize | boolean | true | Strip unsafe HTML |
| options.gfm | boolean | true | Enable GFM extensions |
```

### 7. Configuration

If your tool uses a config file or environment variables, document them completely. Don't make people read source code to find out what `TIMEOUT_MS` means.

```markdown
## Configuration

| Variable | Default | Description |
|----------|---------|-------------|
| PORT | 3000 | HTTP server port |
| DATABASE_URL | — | PostgreSQL connection string |
| LOG_LEVEL | info | debug \| info \| warn \| error |
```

### 8. Contributing

Even a short contributing section helps.

```markdown
## Contributing

1. Fork the repo
2. Create a branch: `git checkout -b feature/my-feature`
3. Make your changes and add tests
4. Run tests: `npm test`
5. Open a pull request

Please follow existing code style (ESLint config included).
```

### 9. License

One line.

```markdown
## License

MIT — see [LICENSE](LICENSE) for details.
```

---

## Templates

### Open Source Library

```markdown
# library-name

Brief one-line description.

![version badge] ![CI badge] ![license badge]

## Installation
\`\`\`bash
npm install library-name
\`\`\`

## Usage
\`\`\`javascript
// minimal working example
\`\`\`

## API
\`\`\`
// table of main methods/options
\`\`\`

## Contributing
// fork, branch, PR process

## License
// MIT or similar
```

### CLI Tool

```markdown
# tool-name

What it does, in one line.

## Installation
\`\`\`bash
npm install -g tool-name
\`\`\`

## Quick Start
\`\`\`bash
tool-name --help
tool-name input.md --output dist/
\`\`\`

## Options
| Flag | Description |
|------|-------------|
| --output, -o | Output directory |
| --watch, -w | Watch for changes |

## Configuration
// config file format if applicable

## License
```

### npm Package

For packages, include the exact import syntax, TypeScript types if applicable, and a note about Node.js version requirements.

```markdown
# package-name

> Brief tagline

\`\`\`bash
npm install package-name
\`\`\`

\`\`\`typescript
import { thing } from 'package-name'
\`\`\`

## Examples
// 2-3 real-world examples

## Requirements
// Node.js 20+, specific peer deps

## License
```

---

## Common README Mistakes

**No installation instructions.** You'd be amazed how many READMEs skip this. Even for obvious things (`npm install`, `pip install`), write it down.

**Code that doesn't work.** This is the biggest credibility killer. If the example in your README throws an error when someone copies it, they're gone. Test your code examples.

**Outdated README.** A README that says "requires Node.js 12" on a project that's been on Node 20 for two years tells contributors that the project isn't actively maintained. Keep it updated.

**No table of contents on long READMEs.** If your README is more than a few screens, add a table of contents at the top. GitHub auto-generates one if you use headings properly.

**All prose, no code.** If your README has three paragraphs describing what your library does but no code showing how to use it, rewrite it. Show, don't tell.

**One paragraph of everything.** Structure matters. Use headings, bullet points, and tables. Developers skim. A well-structured README lets them jump to what they need.

---

## How a Good Markdown Editor Helps

Writing and previewing a README in VS Code's split pane is fine, but there's friction: the preview pane shrinks your editing area, Mermaid diagrams don't render without an extension, and you're in "code mode" rather than "documentation mode."

OpenMark gives you a full-width rendered view of your README — you see exactly how it will look on GitHub. Toggle to edit mode, make a change, toggle back. Mermaid architecture diagrams render immediately. Tables look right. When you export to PDF, you get a clean document you can share with non-technical stakeholders.

For more on what markdown can do for developer documentation — Mermaid diagrams, task lists, footnotes, and more — see [Markdown for Developers: README Files, Documentation, and More](/blog/markdown-for-developers).

For the complete markdown syntax reference, see the [Markdown Cheat Sheet for Mac Users](/blog/markdown-cheat-sheet-mac).

---

## Try OpenMark

Preview your README exactly as GitHub will render it — with working Mermaid diagrams and formatted tables.

**[Download OpenMark on the Mac App Store →](https://apps.apple.com/app/openmark/id)**
$9.99, one-time. Native macOS. No subscription.