TL;DR
Here’s an uncomfortable truth: most developer documentation is garbage. Not mediocre. Not "could be better." Actual garbage that wastes hours of developer time every single day. I’ve written bad docs. You’ve probably written bad docs. The React team, with all their resources, ships docs that confuse people. We’re all guilty here.
But here’s the thing that took me years to figure out: bad documentation isn’t a writing problem. It’s an incentive problem. Nobody gets promoted for great docs. The people who know the code best are usually the worst at explaining it. And documentation rots faster than milk in summer because nobody budgets time to maintain it.
This post is my attempt to lay out everything I’ve learned about writing docs that developers don’t immedia…
TL;DR
Here’s an uncomfortable truth: most developer documentation is garbage. Not mediocre. Not "could be better." Actual garbage that wastes hours of developer time every single day. I’ve written bad docs. You’ve probably written bad docs. The React team, with all their resources, ships docs that confuse people. We’re all guilty here.
But here’s the thing that took me years to figure out: bad documentation isn’t a writing problem. It’s an incentive problem. Nobody gets promoted for great docs. The people who know the code best are usually the worst at explaining it. And documentation rots faster than milk in summer because nobody budgets time to maintain it.
This post is my attempt to lay out everything I’ve learned about writing docs that developers don’t immediately close. Some of this is obvious. Some of it might surprise you. All of it comes from shipping docs that failed spectacularly and slowly figuring out why.
The Four Horsemen of Documentation Hell
Before we talk solutions, let’s be honest about the failure modes. I see these patterns everywhere:
1. The Archaeology Problem
You open the docs. The code example uses a function that was deprecated two years ago. The screenshots show a UI that no longer exists. The installation instructions reference a package that’s been renamed.
This is the most common failure mode, and it’s brutal because it destroys trust. Once a developer encounters one outdated example, they start doubting everything else. They switch to reading the source code directly, which defeats the entire purpose of having documentation.
Why does this happen? Because docs are a snapshot of intent, but code is living and breathing. Nobody sends you a Slack message saying "hey, the refactor I just merged broke three pages of documentation." You find out when users file issues. Or worse, when they just silently churn.
2. The Curse of Knowledge
The person writing the docs already understands the system. They skip over the confusing bits because those bits aren’t confusing to them. They use internal jargon without realizing it. They assume context that doesn’t exist.
I call this "expert blindness" and it’s insidious. The docs seem fine when you review them. They’re technically accurate. But a newcomer reads them and gets lost immediately because the third sentence assumes you know what a "workflow orchestrator" is.
3. The Marketing Infection
Someone in leadership decided the docs should "reinforce brand messaging." Now every page opens with a paragraph about how revolutionary and game-changing the product is. The actual technical content is buried under layers of breathless adjectives.
Developers smell this instantly. It signals that the docs are written for investors, not for them. Trust drops. Engagement drops. They start looking for community wikis or Stack Overflow answers instead.
4. The Kitchen Sink
Everything is documented. Every internal class. Every private method. Every edge case configuration option that three people in the world will ever use.
The result is noise. Developers can’t find the 20% of information they actually need because it’s buried in the 80% they don’t. The search returns fifty results for a simple query. The navigation has forty top-level items.
What Actually Works
Okay, enough complaining. Here’s what I’ve found actually moves the needle:
Start With The User’s Problem, Not Your Architecture
This seems obvious but almost everyone gets it wrong. Your docs should be organized around what developers want to accomplish, not around how your code is structured.
Wrong structure:
Right structure:
See the difference? The first structure makes sense to you because it mirrors your codebase. The second structure makes sense to your users because it mirrors their workflow.
The 30-Second Rule
Every page should answer "why should I care?" within 30 seconds. If a developer lands on your "Configuration" page, they need to immediately understand:
- What problem configuration solves
- Whether they need to configure anything
- Where to go if they do
Bad opening:
"The configuration system supports multiple file formats and provides flexible options for customizing behavior."
That tells me nothing. What behavior? Why would I want to customize it?
Good opening:
"By default, the system documents all code in your repository. Use a config file to exclude test files, dependencies, and build outputs that clutter your docs."
Now I know exactly what configuration is for and whether I need it.
Show Code Before Explaining Code
Developers are pattern matchers. We see working code and can often figure out what it does faster than reading an explanation. Put the code first, then explain the non-obvious parts.
Bad:
"To exclude files from documentation, you need to create a configuration file in your repository root. The file should be named
.docsalot.yamland contain anignorekey with an array of glob patterns..."
Good:
Put this in your repo root. The ignore patterns work like
.gitignore.
The code speaks for itself. The explanation just fills in the one thing you might not guess (it’s like gitignore).
Make Errors First-Class Citizens
Happy path documentation is easy. Error documentation is what separates good docs from great docs.
Every error message your system produces should be searchable in your docs. When a developer Googles an error message, they should land on a page that explains:
- What caused this error
- How to fix it
- What to check if the obvious fix doesn’t work
Example:
This is way more useful than just documenting the happy path and leaving developers to figure out errors on their own.
Write Like You’re Explaining to a Colleague
Not a customer. Not an investor. A colleague who’s smart but doesn’t have your context.
This means:
- Skip the corporate pleasantries ("Welcome to our documentation!")
- Use "you" and "we" liberally
- Admit when something is confusing or has rough edges
- Use technical terminology, but introduce it naturally
Compare:
"The platform provides enterprise-grade documentation capabilities designed to enhance developer productivity and streamline technical communication workflows."
vs.
"This generates API docs from your code. It’s not magic. Garbage in, garbage out. If your code is well-structured with clear naming, you’ll get useful docs. If your codebase is a mess, you’ll get documented mess."
The second version is honest, direct, and actually tells you something useful.
The Freshness Problem (And How To Solve It)
Documentation rot is the killer. Here’s the uncomfortable math: if you have 100 pages of docs and your code changes weekly, you need to review roughly 15 pages per week just to stay current. Nobody does this. Nobody even comes close.
There are really only three approaches that work:
1. Generate What You Can From Source
Any documentation that can be derived from code should be derived from code. Function signatures. Type definitions. API endpoints. Configuration options.
When the code changes, the docs change. There’s no "remember to update the docs" step to forget.
The tradeoff is that generated docs can be sterile. They tell you what something is, not why you’d use it or how it fits with other things. You still need human-written content for the conceptual stuff.
2. Ruthlessly Reduce Surface Area
Every page you write is a page you have to maintain. Be aggressive about what makes it into your docs.
Does that edge case really need its own section? Can you link to external resources instead of duplicating them? Do you need to document that deprecated feature, or can you just remove it?
The best documentation is often the documentation you didn’t write.
3. Automate The Update Detection
Set up alerts for when documented code paths change. If someone modifies a function that has a code example in the docs, that should trigger a review.
This is where automation tools actually shine. Not replacing human judgment, but making sure humans know when judgment is needed.
Organizational Patterns That Work
The Diataxis Framework (Loosely)
There’s a documentation framework called Diataxis that categorizes docs into four types:
- Tutorials (learning-oriented)
- How-to guides (task-oriented)
- Explanations (understanding-oriented)
- Reference (information-oriented)
The key insight: these serve different needs and shouldn’t be mixed. A tutorial walks you through step by step. A reference is for looking things up. Mixing them creates confusing hybrids that serve neither purpose well.
You don’t need to follow Diataxis religiously, but recognizing that "teaching someone" and "providing a lookup resource" are different activities will improve your docs immediately.
Progressive Disclosure
Don’t dump everything on page one. Start simple, then reveal complexity as needed.
Getting started guide: "Install the package, add this config file, run this command."
Configuration reference (linked from getting started): "Here are all 47 configuration options, their defaults, and their interactions."
Beginners get what they need without drowning. Power users can find the deep cuts.
Cross-Linking Aggressively
A developer reading about authentication should be able to jump to error handling, then to deployment, then back. Docs aren’t linear. Don’t force linear navigation.
Common Mistakes I Keep Seeing
Foo/Bar/Baz Examples
Using placeholder names in examples is lazy and makes the code harder to understand. Use realistic examples.
Bad: const result = processData(foo, bar)
Good: const report = generateMonthlyRevenue(transactions, exchangeRates)
The second example tells you something about what the function does just from the names.
Burying The Lede
Don’t make developers scroll through three paragraphs of context before getting to the thing they came for. Put the answer first, then explain it.
Screenshot Overload
Screenshots are maintenance nightmares. Use them sparingly. When you do use them, try to screenshot only the part that matters, not the entire screen.
"For More Information, See..."
This is lazy. If the information is needed, include it. If it’s not needed, don’t link to it. Sending readers on a scavenger hunt is hostile.
Measuring Whether Your Docs Actually Work
Support Ticket Analysis
If developers keep asking the same question, that’s a documentation failure. Track your support tickets and create docs for the top recurring issues.
Time to First Success
How long does it take a new developer to go from "never used this" to "working hello world"? Instrument this. Measure it. Optimize for it.
Search Behavior
What are developers searching for? If they’re searching for "config" and landing on "authentication," your navigation is broken.
Rage Metrics
I’m half joking, but: track "quick succession page views" (user lands on page, quickly leaves, goes somewhere else). That’s a signal the page didn’t answer their question.
A Framework For Writing New Docs
Here’s my checklist when I’m writing a new documentation page:
- What user problem does this solve? If I can’t answer this, I shouldn’t write the page.
- What do they need to know before this? Link to prerequisites clearly.
- What’s the minimal working example? Get them to "it works" as fast as possible.
- What will go wrong? Document the common failure modes.
- Where do they go next? Provide clear next steps.
- Can any of this be generated from code? Automate what can be automated.
- Is this honest? Did I hide any complexity or pretend something is easier than it actually is?
The Uncomfortable Conclusion
Here’s the thing nobody wants to admit: great documentation is expensive. It takes time to write, time to maintain, and time to refactor when your product changes.
Most companies underinvest in docs because the ROI is hard to measure. You can’t A/B test "would this customer have churned if our docs were better?" But the developers who use your product can feel the difference immediately.
My advice: start small. Pick your getting started guide and make it bulletproof. Every step should work. Every command should be copy-pasteable. Every error should be explained.
Then expand from there. Don’t try to boil the ocean. One excellent page is worth more than twenty mediocre ones.
And if you’re using automation to help with the freshness problem, make sure it’s actually helping. Automation that generates useless boilerplate is worse than no automation at all.
References and Further Reading
- Diataxis Documentation Framework - The four-quadrant model for organizing documentation
- Write the Docs Community - Great resources and an active community
- Google’s Technical Writing Course - Free and solid fundamentals
- Stripe’s API Documentation - Still the gold standard for API docs
Good luck. Your users will thank you.