Technical Documentation Writing
This skill activates when writing or improving technical documentation, including README files, API documentation, user guides, and inline code documentation.
When to Use This Skill
Activate when:
- Writing README files
- Creating API documentation
- Writing user guides or tutorials
- Documenting code with comments or docstrings
- Creating architecture or design documents
- Writing changelogs or release notes
README Files
Essential README Structure
Every README should include:
# Project Name
Brief one-liner description of the project.
## Overview
2-3 paragraphs explaining what the project does, why it exists, and who it's for.
## Features
- Key feature 1
- Key feature 2
- Key feature 3
## Installation
### Prerequisites
- Requirement 1 (with version)
- Requirement 2 (with version)
### Install Steps
Clone repository
git clone https://github.com/user/project.git cd project
Install dependencies
npm install # or pip install -r requirements.txt, mix deps.get, etc.
Configure
cp .env.example .env
Edit .env with your settings
Run
npm start
## Quick Start
Minimal example to get started
npm start
## Usage
### Basic Example
// Clear, runnable example const example = new Project() example.doSomething()
### Advanced Usage
More complex examples with explanations.
## Configuration
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| `apiKey` | string | - | API key for authentication |
| `timeout` | number | 5000 | Request timeout in ms |
## API Reference
Link to detailed API documentation or include core APIs here.
## Development
### Setup Development Environment
Development-specific setup
npm install --dev npm run setup
### Running Tests
npm test npm run test:coverage
### Building
npm run build
## Contributing
Please read [CONTRIBUTING.md](https://github.com/vinnie357/claude-skills/blob/HEAD/plugins/core/skills/documentation/CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
## License
This project is licensed under the MIT License - see the [LICENSE](https://github.com/vinnie357/claude-skills/blob/HEAD/plugins/core/skills/documentation/LICENSE) file for details.
## Acknowledgments
- Credits
- Inspirations
- Related projects
## Support
- Documentation: [https://docs.example.com](https://docs.example.com)
- Issues: [https://github.com/user/project/issues](https://github.com/user/project/issues)
- Discussions: [https://github.com/user/project/discussions](https://github.com/user/project/discussions)
README Best Practices
- Start with a clear one-liner: Immediately tell readers what the project does
- Include badges: Build status, coverage, version, license
- Show, don't tell: Use code examples liberally
- Keep it scannable: Use headers, lists, and code blocks
- Make examples runnable: Readers should be able to copy-paste and run
- Include visual aids: Screenshots, diagrams, GIFs when appropriate
- Update regularly: Keep documentation in sync with code
- Think about newcomers: Write for someone seeing the project for the first time
API Documentation
Documenting Functions
Elixir (@doc):
@doc """
Calculates the sum of two numbers.
## Parameters
- `a` - The first number (integer or float)
- `b` - The second number (integer or float)
## Returns
The sum of `a` and `b`.
## Examples
iex> Math.add(2, 3)
5
iex> Math.add(2.5, 3.7)
6.2
"""
@spec add(number(), number()) :: number()
def add(a, b) do
a + b
endJavaScript (JSDoc):
/**
* Calculates the sum of two numbers.
*
* @param {number} a - The first number
* @param {number} b - The second number
* @returns {number} The sum of a and b
*
* @example
* add(2, 3)
* // => 5
*/
function add(a, b) {
return a + b
}Python (docstring):
def add(a: float, b: float) -> float:
"""
Calculate the sum of two numbers.
Args:
a: The first number
b: The second number
Returns:
The sum of a and b
Examples:
>>> add(2, 3)
5
>>> add(2.5, 3.7)
6.2
Raises:
TypeError: If arguments are not numbers
"""
return a + bRust (doc comments):
/// Calculates the sum of two numbers.
///
/// # Arguments
///
/// * `a` - The first number
/// * `b` - The second number
///
/// # Returns
///
/// The sum of `a` and `b`
///
/// # Examples
///
/// ```
/// use mylib::add;
///
/// assert_eq!(add(2, 3), 5);
/// assert_eq!(add(2.5, 3.7), 6.2);
/// ```
pub fn add(a: f64, b: f64) -> f64 {
a + b
}Module/Class Documentation
Document the purpose, usage, and public API:
defmodule MyApp.UserManager do
@moduledoc """
Manages user accounts and authentication.
The UserManager provides functions for creating, updating, and authenticating
users. It handles password hashing, session management, and user validation.
## Usage
# Create a new user
{:ok, user} = UserManager.create_user(%{
email: "alice@example.com",
password: "secure_password"
})
# Authenticate
{:ok, user} = UserManager.authenticate("alice@example.com", "secure_password")
# Update user
{:ok, updated} = UserManager.update_user(user, %{name: "Alice Smith"})
## Configuration
Configure in `config/config.exs`:
config :my_app, MyApp.UserManager,
password_min_length: 8,
session_timeout: 3600
"""
endAPI Endpoint Documentation
Document RESTful APIs clearly:
## Endpoints
### Create User
Creates a new user account.
**Endpoint:** `POST /api/users`
**Authentication:** Not required
**Request Body:**
{ "email": "alice@example.com", "password": "secure_password", "name": "Alice Smith" }
**Response (201 Created):**
{ "id": "123", "email": "alice@example.com", "name": "Alice Smith", "created_at": "2024-01-15T10:30:00Z" }
**Error Responses:**
- `400 Bad Request` - Invalid input `{"error": "validation_error", "details": {"email": ["must be a valid email address"], "password": ["must be at least 8 characters"]}}`
- `409 Conflict` - Email already exists `{"error": "email_taken", "message": "An account with this email already exists"}`
**Example:**
curl -X POST https://api.example.com/users \ -H "Content-Type: application/json" \ -d '{ "email": "alice@example.com", "password": "secure_password", "name": "Alice Smith" }'
User Guides and Tutorials
Tutorial Structure
# Tutorial: Building Your First [Feature]
## What You'll Build
Brief description of the end result.
## Prerequisites
- Knowledge requirement 1
- Installed tool 1
- Account/access requirement
## Step 1: [First Major Step]
Explanation of what we're doing and why.
// Code for this step
**What's happening here:**
- Explanation of key line 1
- Explanation of key line 2
## Step 2: [Next Step]
Continue with incremental steps...
## Testing
How to verify it works.
## Next Steps
- Related tutorial 1
- Advanced topic 1
- Further reading
Tutorial Best Practices
- Show working code first: Let readers see the goal before diving into details
- Explain the 'why': Don't just show what to do, explain reasoning
- Incremental steps: Each step should build on the previous
- Include checkpoints: Ways to verify progress
- Provide complete code: Include a repository or final code snippet
- Anticipate problems: Address common mistakes
- Link to references: Point to relevant API docs and resources
Inline Code Documentation
When to Write Comments
DO write comments for:
- Complex algorithms or business logic
- Non-obvious decisions ("why" not "what")
- Workarounds for bugs or limitations
- Public APIs and exported functions
- Configuration and constants
DON'T write comments for:
- Obvious code
- What the code does (prefer clear naming)
- Outdated information
- Commented-out code (use version control)
Good Comment Examples
# Good: Explains WHY
# Use exponential backoff to avoid overwhelming the API after rate limit errors
defp retry_with_backoff(attempt) do
:timer.sleep(:math.pow(2, attempt) * 1000)
end
# Bad: Explains WHAT (obvious from code)
# Multiply 2 to the power of attempt and multiply by 1000
defp retry_with_backoff(attempt) do
:timer.sleep(:math.pow(2, attempt) * 1000)
end
# Good: Documents workaround
# NOTE: Using String.to_existing_atom because the Erlang VM limits atoms to ~1M.
# All valid status atoms are pre-defined in this module.
def parse_status(status_string) do
String.to_existing_atom(status_string)
end
# Good: Explains business rule
# Users must be at least 13 years old per COPPA regulations
@minimum_age 13Architecture Documentation
Architecture Decision Records (ADR)
Document significant architectural decisions:
# ADR 001: Use PostgreSQL for Primary Database
## Status
Accepted
## Context
We need to choose a database for our application that supports:
- ACID transactions
- Complex queries with joins
- JSON data storage
- Full-text search
- Horizontal scalability (future requirement)
## Decision
We will use PostgreSQL as our primary database.
## Consequences
### Positive
- Mature, stable, well-documented
- Excellent JSON support with JSONB
- Built-in full-text search
- Strong consistency guarantees
- Large ecosystem of tools and extensions
- Can scale with read replicas and partitioning
### Negative
- More complex to operate than simpler databases
- Vertical scaling has limits (though sufficient for our needs)
- Requires more server resources than lighter alternatives
### Neutral
- Team needs to learn PostgreSQL-specific features
- May need to hire PostgreSQL expertise as we scale
## Alternatives Considered
- **MySQL**: Weaker JSON support, less feature-rich
- **MongoDB**: No ACID guarantees, eventual consistency issues
- **SQLite**: Not suitable for multi-user web applicationsChangelog Documentation
Follow Keep a Changelog format:
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- New feature in development
## [1.2.0] - 2024-01-15
### Added
- User profile pictures
- Email notification preferences
- Dark mode support
### Changed
- Improved search performance by 40%
- Updated UI to match new brand guidelines
### Fixed
- Login redirect loop on Safari
- Memory leak in background sync process
### Deprecated
- Old `/v1/users` endpoint (use `/v2/users` instead)
## [1.1.0] - 2024-01-01
### Added
- Two-factor authentication
- Export user data to JSON
### Security
- Fixed XSS vulnerability in comment rendering
## [1.0.0] - 2023-12-15
### Added
- Initial release
- User registration and authentication
- Basic user profilesDocumentation Tools
Documentation Generators
- Elixir: ExDoc -
mix docs - JavaScript: JSDoc, TypeDoc
- Python: Sphinx, MkDocs
- Rust: rustdoc -
cargo doc - Static sites: VitePress, Docusaurus, GitBook
Diagram Tools
- Mermaid: Diagrams in Markdown ```
`mermaid graph TD A[User] -->|Requests| B[Load Balancer] B --> C[Web Server 1] B --> D[Web Server 2] C --> E[Database] D --> E``` - PlantUML: UML diagrams as code
- Excalidraw: Hand-drawn style diagrams
- Draw.io: Flowcharts and diagrams
Documentation Style Guide
Writing Style
- Use active voice: "The function returns" not "The value is returned"
- Be concise: Remove unnecessary words
- Use present tense: "Returns" not "Will return"
- Be specific: "Timeout in milliseconds" not "Timeout value"
- Avoid jargon: Or explain it when necessary
- Use examples: Show, don't just tell
Formatting Conventions
- Code: Use
backticksfor inline code - Commands: Show with
$prefix or in code blocks - File paths: Use
code formatting - Emphasis: Use bold for important points, *italic* for slight emphasis
- Lists: Use bullets for unordered, numbers for sequential steps
- Headers: Use sentence case, not title case
Code Examples
- Complete: Include all necessary imports and setup
- Runnable: Readers should be able to copy and run
- Realistic: Use meaningful variable names and realistic data
- Commented: Explain non-obvious parts
- Tested: Ensure examples actually work
- Current: Keep in sync with latest API
Documentation Maintenance
Keeping Docs Updated
- Update documentation in the same PR as code changes
- Review docs during code review
- Set up doc linting (broken links, outdated examples)
- Schedule regular documentation audits
- Use version tags in examples when API changes
- Mark deprecated features clearly
Documentation Testing
# Elixir doctests - examples in docs are actual tests
defmodule Math do
@doc """
Adds two numbers.
## Examples
iex> Math.add(2, 3)
5
"""
def add(a, b), do: a + b
end/// Adds two numbers.
///
/// # Examples
///
/// ```
/// assert_eq!(add(2, 3), 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}Key Principles
- Write for your audience: Tailor complexity to reader's experience level
- Show examples: Code examples are worth a thousand words
- Keep it current: Outdated docs are worse than no docs
- Make it scannable: Use headers, lists, code blocks, and white space
- Explain the 'why': Help readers understand reasoning, not just steps
- Start simple: Begin with quickstart, then go deeper
- Test documentation: Ensure examples run and links work
- Iterate based on feedback: Improve based on user questions and confusion