Your README is a Landing Page, Not Your Documentation
Stop treating READMEs like documentation dumps. Learn why README sprawl kills engagement and how to maintain disciplined, focused landing pages that actually convert readers into users.
- tags
- #Documentation #Readme #Open-Source #Developer-Tools #Technical-Writing #Markdown #Github #Documentation-Patterns #Software-Engineering #Best-Practices #Api-Documentation #Crates-Io #Npm #Pypi #Repository-Management #Code-Hygiene #Documentation-Sprawl #Content-Strategy #Engineering-Culture #Oss-Maintenance
- categories
- Developer-Tools Best-Practices
- published
- reading time
- 18 minutes
Every feature you add to your project makes your README longer. Every API you document inline pushes the Quick Start section further down. Every example you add “for clarity” moves the installation instructions off the first screen.
Before you know it, your README is 800 lines. New users bounce. Contributors get lost. Your carefully crafted introduction sits at the top of a wall of text that nobody reads past line 50.
This isn’t a documentation problem. It’s a marketing problem.
Table of Contents
- The Uncomfortable Truth - READMEs are marketing
- The Sprawl Pattern - How it happens
- Why Sprawl Happens - Engineering mindset traps
- The Landing Page Mindset - Think like a product page
- The README Formula - Hero, pain point, features, installation
- The Extraction Pattern - Surgical reduction in 4 steps
- Real Example: error-envelope - ~500→235 lines (53% reduction)
- The “But What About…” Questions - Objections answered
- The Discipline Framework - Line budgets and maintenance rules
- The Templates - Copy-paste starting points
- The Hard Part: Saying No - Defending your line budget
- The Documentation Hierarchy - Where different content belongs
- The Anti-Patterns - Common README killers
- The Psychology of Scrolling - User behavior patterns
- Start Today - Actionable next steps
The Uncomfortable Truth
Not marketing in the sleazy sense. Marketing in the:
- “I have 30 seconds to convince someone this solves their problem” sense
- “Every line needs to earn its place” sense
- “If they’re still reading at line 200, you’ve already lost” sense
Your README isn’t where people learn your API. It’s where they decide whether to learn your API at all.
The Sprawl Pattern
The pattern is predictable:
- Start clean - Minimal README with one example
- Add “just one more thing” - Someone asks about error handling, so you add a section
- Duplicate for clarity - Show the same concept in three languages “to be helpful”
- Inline everything - Full API reference because “it’s convenient”
- Hit 800+ lines - README is now a documentation dump
Why Sprawl Happens
The engineering mindset works against us here.
“Let me just add one more example”
You’re proud of your error handling. You want to show it off. So you add an example. Then someone asks about retries, so you add that too. Then distributed tracing. Then rate limiting.
Before you know it, you have 15 examples in your README. Each one made sense in isolation. Together, they’re overwhelming.
“I’ll document it while I remember”
You just added a new feature. Your brain is full of context. The easiest thing is to document it right there in the README where everyone will see it.
Except “everyone will see it” becomes “nobody will find it” when your README is 700 lines long.
“But comprehensive is better”
No. Comprehensive is overwhelming.
Users don’t need comprehensive in your README. They need:
- Does this solve my problem?
- Can I install it?
- Can I make it work in 5 minutes?
- Where do I go to learn more?
That’s it. Everything else is resistance.
“It’s already explained somewhere else”
Repetition happens more often than you might think as documentation grows. You add a diagram showing the architecture. Then later, you add a table with the same information “for clarity.” Then someone adds prose explaining both. Before long, the same concept is documented three times in different formats.
Each version made sense when added. But together, they create bloat.
The pattern: Search before you add. If the information exists, link to it. Don’t duplicate it.
The Landing Page Mindset
Your README is a front door. You don’t stack everything in the front yard blocking the entrance. You present a nice landscape, help visitors find the door, and structure your content into dedicated spaces that can be easily discovered and understood.
A good README tells people:
- What this is
- Why they should care
- Exactly how to use it in the fewest steps possible
Your README should be less about “what” and more about “why,” with the “whats” connecting directly to the “whys.”
Then link out to detailed documentation (installation guides, tutorials, API reference, example gallery, migration guides).
The README Formula
People look for libraries because they’re trying to solve a problem. Your README needs to validate their pain point before showing your solution. If they can’t figure out whether this solves their problem in the first 30 seconds, they bounce.
Here’s the structure that works:
1. Hero Section (Lines 1-10)
One sentence. What does this do? Who is it for?
This is your value proposition: the benefit someone gets from using your project, stated clearly enough that they understand it in 5 seconds.
| |
Not:
| |
One sentence. Value proposition. Done.
2. Social Proof (Lines 11-15)
Badges. Keep them in one line if possible.
| |
3. Quick Example (Lines 16-30)
One working example. 5-10 lines. Shows the primary use case.
| |
Not three examples. Not “here’s basic, here’s intermediate, here’s advanced.” One example.
Hero vs Quick Start confusion:
Many READMEs duplicate content between a hero example (top) and a Quick Start section (later). This is the easiest place to create redundancy.
Differentiate them:
- Hero example - Shows “batteries included” functionality. Demonstrates the full power with integrations, multiple features, complete output. This is your sales pitch.
- Quick Start section (if you have one) - Shows minimal, initial use case. Ease-in to the product. Just enough to get something working.
If your hero already shows the complete picture, your Quick Start should be tiny (3-5 lines) and show the simplest possible usage. Or skip Quick Start entirely and link to examples/.
Example (error-envelope):
- Hero: Shows anyhow integration + validation + structured output (full power)
- Quick Start:
Error::not_found("...").with_trace_id("...")(minimal builder pattern)
Don’t repeat the hero example in Quick Start. If they’re the same, you’re wasting space.
3.5. The Problem Statement (Optional but Powerful)
Before listing features, consider articulating the pain point:
| |
This validates the reader’s experience. If they’ve felt this pain, they immediately know: “This is for me.”
Don’t skip this. The reader needs to see their problem reflected back before they trust your solution.
4. Features (Lines 31-50)
Bullet list. Each feature is one line with a link to detailed docs.
| |
Notice the pattern: Hook + link. Not full explanations inline.
5. Installation (Lines 51-60)
Simple. Cargo.toml, npm install, pip install. One command.
| |
Optional features if relevant, but keep it short.
6. Table of Contents (Optional, Lines 61-70)
Only if your README is still over 200 lines (it shouldn’t be). Keep it to 4-5 top-level links.
| |
7. What’s Next Section (Lines 71-80)
Links to real documentation.
| |
Total: 80-150 lines.
Everything else lives in separate files.
The Extraction Pattern
You’ve already got an 800-line README. How do you fix it?
Step 1: Create Dedicated Files
Don’t rewrite. Extract.
| |
Step 2: Move Content (Don’t Delete)
Copy sections from README to dedicated files. Preserve everything. This isn’t about losing content - it’s about organizing it.
| |
Step 3: Replace with Hooks
Where you had 150 lines of API documentation, replace with 20 lines of hooks:
| |
Step 4: Measure the Result
| |
Target: 200-400 lines. If you’re still over 400, extract more.
Real Example: error-envelope
I recently did this with error-envelope , a Rust crate for HTTP error responses.
Before:
- README.md: ~500 lines
- Full API reference inline (18 constructors, full signatures)
- Complete error codes table (18 rows with descriptions)
- 13 mermaid diagrams explaining architecture
- Multiple framework integration examples
- Architecture explanations mixed throughout
Problem: New users had to scroll past 200+ lines of API documentation, diagrams, and architecture discussion to find the Quick Start.
After (surgical extraction):
- README.md: 235 lines (53% reduction)
- API.md: 364 lines (complete API reference)
- ERROR_CODES.md: 167 lines (full error code documentation)
- ARCHITECTURE.md: 272 lines (design decisions with 4 essential mermaid diagrams)
README changes:
- API section reduced from 90 lines to 30 lines (8 common constructors + link to API.md)
- Error codes reduced from 18-row table to 5-row table (most common codes + link)
- Mermaid diagrams reduced from 13 to 4 (moved 9 to ARCHITECTURE.md)
- Table of contents trimmed from 11 sections to 6 key links
Result: The README now serves as a landing page. If you want the full API, you click a link. If you want to see all error codes, you click a link. But if you just want to understand what this crate does and whether it solves your problem, you get your answer in the first 50 lines.
The “But What About…” Questions
“But users expect comprehensive READMEs”
No. Users expect to find information quickly. A 600-line README makes that harder, not easier.
GitHub’s search is mediocre. Users scroll, not search. Long READMEs increase time-to-answer, not decrease it.
“But I want everything in one place”
Everything is in one place: your repository. Just not in one file.
Think about it: would you put your entire codebase in one file because “it’s convenient”? No. You organize into modules.
Documentation works the same way.
“But what if people don’t click the links”
If they don’t click links in a 200-line README, they definitely won’t scroll through a 600-line README.
Links are lower friction than scrolling. Separate files are easier to navigate than one massive file. This is why documentation sites exist.
“But more detail shows thoroughness”
To other engineers, maybe. To users evaluating your project, it shows lack of focus.
“This README is so long they must be serious” is not a thought anyone has ever had. “This README is so long I’ll come back later” is a thought everyone has had.
The Discipline Framework
Here’s how to maintain README discipline over time:
Rule 1: Line Budget
Set a target based on project scope:
- Single-purpose library: 200-400 lines max
- Framework or tool: 400-600 lines max
- Monorepo/workspace (multiple crates): 500-800 lines max
- Large platform: 800-1000 lines max (but consider splitting to docs/)
The key: set a number and stick to it. Every time you add a section, something else must get extracted or trimmed.
Examples:
serde(single crate, focused): ~200 linestokio(runtime with multiple components): ~500 linesrust-lang/rust(massive monorepo): ~800 lines, but heavily links out
If you’re a single library and hitting 600 lines, you have sprawl. If you’re a workspace with 8 crates and at 600 lines, you’re probably fine.
Rule 2: One Example Rule
Each concept gets one example in the README. More examples go in examples/ or EXAMPLES.md.
You don’t need:
- Basic example
- Intermediate example
- Advanced example
- Edge case example
You need: The most common example. That’s it.
Rule 3: No Inline API Docs
Full API documentation belongs in:
- docs.rs for Rust crates
- API.md or docs/ directory for GitHub
- Your documentation site
README gets: 5-8 most common functions + link to full docs.
understanding
what this does?"} question2{"Can it be shown
in 10 lines
or less?"} question3{"Is it more important
than existing
content?"} end subgraph actions["Actions"] add_readme["Add to README"] add_docs["Add to API.md/docs/"] extract["Extract existing
content first"] link["Add link in README"] end new --> question1 question1 -->|No| add_docs question1 -->|Yes| question2 question2 -->|No| add_docs question2 -->|Yes| question3 question3 -->|No| extract question3 -->|Yes| add_readme add_docs --> link extract --> add_readme style decision fill:#3A4A5C,stroke:#6b7280,color:#f0f0f0 style actions fill:#3A4C43,stroke:#6b7280,color:#f0f0f0
Rule 4: Resist “Just One More”
Every new feature doesn’t need a README section. Most features need:
- A line in the Features section (with link to docs)
- An entry in CHANGELOG.md
- Documentation in API.md or docs/
Not:
- A new README section
- Another example inline
- A detailed explanation of internals
The Templates
Use these as starting points.
Minimal README Template (Library/Tool)
| |
Total: ~40 lines.
Comprehensive README Template (Framework/Platform)
| |
Total: ~80-120 lines.
The Documentation Hierarchy
Here’s where different content belongs:
| Content Type | Location | Why |
|---|---|---|
| Value proposition | README | First thing users see |
| One working example | README | Proves it works quickly |
| Installation | README | Reduces friction to try |
| Feature bullets | README | Helps users decide if relevant |
| Complete API reference | API.md or docs.rs | Searchable, comprehensive |
| All error codes | ERROR_CODES.md | Reference material |
| Multiple examples | examples/ or EXAMPLES.md | Shows flexibility without cluttering |
| Design decisions | ARCHITECTURE.md | For contributors and curious users |
| Migration guides | MIGRATION.md | Version-specific, doesn’t age well in README |
| Tutorials | docs/ directory | Step-by-step, too long for README |
| Community content | GitHub Wiki | User-contributed, not core |
The Anti-Patterns
Watch out for these README killers:
1. The Kitchen Sink
| |
Fix: Extract to API.md. Show 5-8 common constructors in README with link to full docs.
2. The Example Gallery
| |
Fix: Keep ONE basic example in README. Move everything else to examples/ directory or EXAMPLES.md.
3. The Historian
| |
Fix: History belongs in a blog post or HISTORY.md. README gets 2-3 sentences max on “why this exists.”
4. The Completionist
| |
Fix: README shows the primary installation method (cargo add, npm install). Everything else goes in INSTALLATION.md or docs/INSTALL.md.
5. The Inline Troubleshooter
| |
Fix: Troubleshooting belongs in docs/TROUBLESHOOTING.md or GitHub Discussions. Link to it from README.
The Psychology of Scrolling
In the first 10 seconds, they decide if this solves their problem. In the next 20 seconds, they look for proof it works (Quick Start). Then they check how hard it is to set up (Installation). After that, they either try it or bounce to another tab.
Every line between the title and Quick Start is friction. Your README competes with 10 other open tabs. Make it easy to choose yours.
The Hard Part: Saying No
The hardest part of README discipline isn’t the refactoring. It’s saying no to well-meaning additions.
Contributor: “I added a new feature, here’s a PR with 50 lines of README docs.”
You: “Thanks! Let’s add a bullet in the Features section with a link to docs/FEATURE_X.md instead.”
Contributor: “But people need to know how it works!”
You: “They do - in the docs. The README is for deciding whether to use it, not learning how to use it.”
This feels harsh. It feels like you’re hiding information. You’re not. You’re organizing information so users can find it.
Start Today
The longer you wait, the harder extraction becomes. Start with one section:
wc -l README.md- Check current length- Pick the longest section (API reference, error codes, examples)
- Extract to dedicated file (API.md, ERROR_CODES.md, EXAMPLES.md)
- Replace with 3-5 line summary + link
- Commit: “Extract [section] from README to reduce sprawl”
Set a line budget for your project scope. Defend it. Every new feature doesn’t need a README section - most need a bullet + link.
More hooks, less sprawl.