The Documentation Paradox: What Should You Actually Document?


There's an uncomfortable truth about software documentation that nobody wants to admit:

Most documentation is solving the wrong problem.

Not because documentation itself is bad. But because we're documenting things that shouldn't need documentation in the first place.

The Documentation Dilemma

Every engineering team faces this cycle:

Engineers spend hours writing documentation. It gets skimmed once during onboarding. It's never updated. Six months later, it's wrong. Now it's dangerous—misleading developers who trust it.

The question isn't "should we write documentation?" The question is "what should we be documenting, and why?"

The Myth of "No Documentation"

There's a popular belief that great products don't need documentation. People point to consumer products as proof:

"The iPhone didn't ship with a manual!"

This is misleading. The original iPhone in 2007 did have a comprehensive 124-page user guide—it was just delivered digitally rather than in the box, an innovative decision at the time that saved paper and shipping costs.

"Google Search doesn't need a tutorial!"

True for basic searches. But Google provides extensive help documentation for advanced search operators, troubleshooting, and power user features. The basic interface is simple by design, but complexity is documented when needed.

"Stripe's API is so intuitive you don't need docs!"

This gets it backwards. Stripe is famous for having some of the best and most thorough documentation in the industry, which is precisely why developers love it. Developers absolutely read Stripe's docs—the documentation is so clear and comprehensive that it makes the integration process dramatically easier than competitors.

The real pattern: Great products combine intuitive design with excellent documentation. They don't substitute one for the other.

What We Get Wrong About Documentation

The problem isn't documentation itself. The problem is what we choose to document.

We Document to Fix Bad Design

Instead of making error messages clear, we write guides explaining cryptic error codes.

Instead of using intuitive naming, we explain what confusingly-named functions do.

Instead of designing obvious workflows, we create step-by-step tutorials for basic operations.

We're adding a layer of explanation instead of fixing the root cause.

This is documentation as a Band-Aid on design problems.

We Confuse Two Types of Complexity

Not all complexity is the same. There's a crucial distinction:

Essential Complexity: Inherent to the problem domain

  • Distributed systems have unavoidable edge cases
  • Payment processing has regulatory requirements
  • Authentication flows have security considerations
  • Complex business logic reflects complex business rules

Accidental Complexity: Introduced by poor design choices

  • Unclear variable names
  • Inconsistent patterns across the codebase
  • Cryptic error messages
  • Confusing user interfaces

Essential complexity should be documented. Accidental complexity should be eliminated.

What Actually Deserves Documentation

At Stripe, a feature isn't considered "done" until its corresponding documentation is written, reviewed, and published. But Stripe doesn't document to compensate for poor design—they document to enhance already-excellent design.

Document these things:

Architectural Decisions and Trade-offs

  • Why did you choose this database?
  • What performance trade-offs did you make?
  • Why microservices instead of a monolith?

These decisions have context that code alone can't communicate. Future developers need to understand the "why" to avoid undoing good decisions or repeating past mistakes.

Non-Obvious Behaviors and Edge Cases

  • How does the system behave under specific failure modes?
  • What happens when two users modify the same resource simultaneously?
  • How does caching interact with database updates?

Edge cases aren't always obvious from reading code. Document the scenarios that took you by surprise so others don't have to discover them the hard way.

Complex Domain Logic

  • Business rules that reflect real-world complexity
  • Regulatory requirements and compliance considerations
  • Mathematical algorithms or specialized domain knowledge

When complexity is inherent to the domain, documentation helps developers navigate it.

Migration Paths and Breaking Changes

  • How to upgrade between versions
  • What breaks and how to fix it
  • Why the breaking change was necessary

Developers need guidance through transitions. Good documentation turns potential disasters into smooth upgrades.

What Doesn't Deserve Documentation

Don't document:

Basic Usage of Well-Designed Features

If users need documentation to understand how to use your core product, your design needs work. Basic operations should be self-evident.

What the Code Does

getUserById(userId) doesn't need documentation explaining that it retrieves a user by their ID. The code documents itself through clear naming.

Error Messages

Don't write a separate document explaining error codes. Make the error messages themselves clear:

Bad: Error 422 (requires documentation) Good: Invalid email format. Expected: user@domain.com (self-explanatory)

Workarounds for Design Flaws

If you're documenting complex workarounds, you're documenting a problem that should be fixed in the code instead.

Better Alternatives to Traditional Documentation

1. Self-Documenting Code

Use explicit types:

// Good - types are documentation
function createUser(email: string, name: string): User

// Bad - requires separate documentation
function proc(e, n, opts)

TypeScript types serve as always-up-to-date documentation that's enforced by the compiler—far more reliable than a wiki page.

Choose clear names:

// Good - purpose is obvious
const activeUserCount = users.filter(u => u.isActive).length

// Bad - requires explanation
const c = arr.filter(x => x.f).length

2. Working Examples Over Explanations

Stripe's documentation succeeds because it provides personalized, copy-paste-ready code examples that developers can run immediately. One working example teaches more than pages of prose.

Show working code. Don't explain how it works—demonstrate it working.

3. Better Error Messages

Instead of documenting what errors mean, make errors self-explanatory:

Bad:
Error: VALIDATION_FAILED

Better:
Error: Email validation failed
- Received: "user@"
- Expected format: "user@domain.com"
- Valid example: "john@example.com"

4. Interactive Documentation

Stripe embeds tools like the Stripe Shell directly into documentation, allowing developers to make live API calls without leaving the page. This transforms passive reading into active learning.

The Documentation Decision Framework

Before writing documentation, ask these questions:

1. Is this obvious from the code?

If yes, improve the code instead of documenting it. Clear naming, explicit types, and intuitive structure eliminate the need for explanation.

2. Is this discoverable through the interface?

If users should be able to figure this out by exploring, improve discoverability. Add hints, tooltips, or contextual help directly in the interface.

3. Can the error message explain this?

If users hit this problem, can the error message guide them to the solution? Invest in error messages before documentation.

4. Is this essential complexity or accidental complexity?

Essential: Document it well. Accidental: Fix the design.

The Real-World Impact

Research on documentation quality reveals interesting patterns:

At Stripe, documentation contributions are included in career ladders and performance reviews for engineers. When writing quality documentation is recognized and rewarded, it becomes a valued skill rather than an afterthought.

Stripe's developer experience success comes from combining an intuitive API with excellent documentation, supported by tools like CLI integration, VS Code extensions, and test mode environments.

The lesson: Great products don't choose between good design and good documentation. They excel at both and understand when each is appropriate.

A Balanced Approach

The goal isn't to eliminate documentation. The goal is to document the right things.

Self-evident for simple things:

  • Intuitive interfaces
  • Clear naming
  • Explicit error messages
  • Obvious workflows

Well-documented for complex things:

  • Architectural decisions
  • Domain complexity
  • Edge cases and gotchas
  • Migration paths

Nothing that documents around bad design:

  • Don't explain confusing UX
  • Don't decode cryptic errors
  • Don't provide workarounds

Practical Steps

1. Audit Your Existing Documentation

For each document, ask:

  • Does this explain how to use something basic? → Consider redesigning for simplicity
  • Does this explain what something does? → Consider better naming
  • Does this explain an error code? → Consider better error messages
  • Does this explain why a decision was made? → Keep and maintain this

2. Shift Your Investment

Spend less time writing:

  • How-to guides for basic features
  • Explanations of what code does
  • Documentation of error codes

Spend more time on:

  • Architecture Decision Records (ADRs)
  • Complex domain logic explanation
  • Edge case documentation
  • Living code examples

3. Make Documentation Living

Stripe built custom tooling to create rich, interactive documentation experiences beyond standard Markdown capabilities. While you don't need custom tooling, make documentation:

  • Close to the code (comments, docstrings)
  • Executable (runnable examples)
  • Testable (examples that break when they become outdated)

The Bottom Line

The best documentation isn't the longest, most comprehensive, or most beautifully designed.

The best documentation is the documentation you don't need to write because the system is self-explanatory.

And when complexity is genuinely necessary, the best documentation enhances understanding rather than compensates for confusion.

Before you write another doc:

  1. Could better design eliminate this need?
  2. Could better error messages solve this?
  3. Could better naming make this obvious?
  4. Is this essential complexity that deserves explanation?

If you answered yes to 1-3, improve the design. If you answered yes to 4, document it well.

Document the essential. Design away the accidental.

That's how you build products developers love.


What documentation have you written that you later realized should have been better design? Share your experience in the comments.


Sources

MacRumors Forums. (2007). "iPhone User Guide Posted." https://forums.macrumors.com/threads/iphone-user-guide-posted.322079/

Moesif Blog. (2023). "The Stripe Developer Experience and Docs Teardown." https://www.moesif.com/blog/best-practices/api-product-management/the-stripe-developer-experience-and-docs-teardown/

Kenneth Auchenberg. "Insights from building Stripe's developer platform & API developer experience." https://kenneth.io/post/insights-from-building-stripes-developer-platform-and-api-developer-experience-part-1

Apidog Blog. (2025). "Why I Love Stripe Docs (API Documentation Best Practices)." https://apidog.com/blog/stripe-docs/


Written by Sharath Chandra Odepalli

LinkedIn 

Comments

Popular posts from this blog

Stop Building: Why Less Is More in Software Development

Clarity: The Most Underrated Skill in Technology

The Transparency Era: What California's New AI Law Means for Tech Builders