name: github-readme description: How to write a compelling GitHub README that makes developers instantly understand and want to use your library.
Writing a GitHub README That Converts
Developers skim READMEs. You have 5 seconds to show them why your library matters. Structure everything around that constraint.
Structure (Top to Bottom)
1. Banner + Badges (optional but polished)
Centered banner image + npm version, downloads, license badges. Makes the repo look established.
<p align="center">
<img src="banner.png" alt="project-name" width="100%" />
</p>
<p align="center">
<b>One-sentence value proposition.</b>
</p>
<p align="center">
<a href="https://www.npmjs.com/package/NAME"><img src="https://img.shields.io/npm/v/NAME.svg" alt="npm version"></a>
<a href="https://www.npmjs.com/package/NAME"><img src="https://img.shields.io/npm/dm/NAME.svg" alt="npm downloads"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
</p>
2. Before/After Hook (CRITICAL)
The single most effective way to sell a dev tool. Show the ugly boilerplate first, then your clean alternative. Both must produce the same result so the comparison is direct.
**Before:**
[manual boilerplate code]
**After:** [project-name] does the same in one line:
[your clean code]
Rules:
- Same operation in both examples — don't show a simple case in "before" and a complex one in "after"
- Show the output so readers can see what actually happens
- Mention type safety if applicable (e.g., "infers
T | null")
3. Installation
## Installation
\`\`\`sh
npm install your-package
# or bun add / pnpm add / yarn add
\`\`\`
Always include multiple package managers.
4. Defaults / What You Get
Short bullet list of what happens automatically. Use emoji for visual scanning:
## ✨ Defaults
Every call automatically:
- 🛡️ **Feature one** → brief explanation
- ⏱️ **Feature two** → brief explanation
- 🌳 **Feature three** → brief explanation
5. Killer Feature (move it UP)
Whatever makes your library unique — don't bury it at the bottom. If nesting/tracing/reactivity/etc. is the differentiator, it goes right after defaults. Show code + output.
6. Error Handling / Edge Cases
Show all variants in a table so readers can compare at a glance:
| Pattern | On error | Return Type |
|---------|----------|-------------|
| `fn(a)` | returns `null` | `T \| null` |
| `fn(a, fallback)` | returns fallback | `T` |
| `fn.assert(a)` | throws | `T` |
7. Configuration / Options
Use a table for option objects:
| Field | Type | Effect |
|-------|------|--------|
| `label` | `string` | Display name |
| `timeout` | `number` | Abort after N ms |
8. Extensions / Additional API
Each extension gets:
### method signatureheader- 1-sentence description
- Code example with output
9. Configuration
Runtime config + environment variables.
10. Output Reference (if applicable)
Quick symbol/format reference table at the bottom.
11. License
Just "MIT" — one line.
Writing Rules
Lead with value, not philosophy
- ❌ "In the spirit of functional programming..."
- ✅ Show the before/after code comparison
No marketing language
- ❌ "Revolutionary", "blazing fast", "game-changer", "no setup, no dashboards"
- ✅ Specific, technical descriptions
No first person
- ❌ "I built this because..."
- ✅ Let the code speak
Every example needs output
Don't just show the function call — show what gets logged/returned.
Be consistent
If you show fetchUsers() in one example, don't switch to getUsers() in the next. Same function names throughout.
Don't repeat concepts
Each feature appears once. If error handling is covered in a section, don't re-explain it in the API section.
Use emoji headers for skimmability
✨ Defaults, 🛡️ Error Handling, 🚦 Timeouts, 🧰 Extensions, ⚙️ Configuration
Tables over prose
For comparing variants, listing options, or showing output formats — always use a table.
Anti-Patterns
- Wall of text before any code — you lose readers instantly
- Simple/basic examples only — show your library doing something impressive
- Duplicated information — same feature explained in 3 different sections
- Inconsistent examples — different function names, different scenarios across sections
- Missing output — reader has to run code to understand what it does
- Placeholder images — either have a real banner or skip it
- Too many badges — 3-4 max (version, downloads, license, maybe CI status)
Verification
After pushing, always check the README renders correctly on GitHub:
- Banner and badges display centered
- Code blocks have syntax highlighting
- Tables render with proper columns
- Emoji show correctly
- Links work