documentation-writing

Documentation Writing

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "documentation-writing" with this command: npx skills add tejovanthn/rasikalife/tejovanthn-rasikalife-documentation-writing

Documentation Writing

This skill covers best practices for creating effective documentation that developers actually want to read and maintain.

Core Philosophy

Great documentation is:

  • Clear: Easy to understand on first reading

  • Complete: Answers the questions users actually have

  • Current: Kept in sync with code changes

  • Concise: No unnecessary fluff

  • Scannable: Easy to find what you need

  • Practical: Focuses on how-to, not just what

Types of Documentation

  1. README Files

The front door to your project:

Project Name

Brief description (1-2 sentences) of what this does.

Features

  • Key feature 1
  • Key feature 2
  • Key feature 3

Quick Start

```bash npm install npm run dev ```

Visit http://localhost:3000

Project Structure

``` src/ routes/ # Remix routes lib/ # Shared utilities components/ # React components ```

Documentation

Contributing

See CONTRIBUTING.md

License

MIT

Key elements:

  • What it does (immediately)

  • How to get started (quickly)

  • Where to find more information

  • How to contribute

  1. Code Comments

Use sparingly and wisely:

✅ Do explain WHY:

// We batch writes to avoid hitting DynamoDB's 25-item transaction limit const batches = chunk(items, 25);

// Disable cache for this endpoint because user data changes frequently // and stale data causes support tickets. See issue #123 export const loader = async () => { // ... };

✅ Do document complex algorithms:

/**

  • Implements the Luhn algorithm for credit card validation.
  • https://en.wikipedia.org/wiki/Luhn_algorithm */ function validateCardNumber(cardNumber: string): boolean { // Double every second digit from right to left // If doubling results in two digits, add them together // ... }

❌ Don't state the obvious:

// Get the user const user = await getUser(id);

// Check if user exists if (!user) { // Return error return error("Not found"); }

  1. API Documentation

Document public APIs thoroughly:

/**

  • Creates a new user account and sends a welcome email.
  • @param email - User's email address (must be unique)
  • @param password - Plain text password (will be hashed)
  • @param name - User's display name
  • @returns The created user object (without password)
  • @throws {ValidationError} If email is invalid or already exists
  • @throws {EmailError} If welcome email fails to send
  • @example
  • const user = await createUser({
  • email: "user@example.com",
  • password: "secure123",
  • name: "John Doe"
  • });

*/ export async function createUser( email: string, password: string, name: string ): Promise<User> { // Implementation }

  1. Architecture Documentation

Explain the big picture:

Architecture Overview

System Components

Frontend (Remix)

  • Server-side rendering for initial load
  • Progressive enhancement for interactivity
  • Nested routes for UI composition

Backend (SST)

  • Lambda functions for API endpoints
  • DynamoDB for data storage (single table design)
  • S3 for file uploads
  • SES for email sending

Data Flow

  1. User submits form → Remix action
  2. Action validates data
  3. Action calls business logic in src/lib/
  4. Business logic updates DynamoDB
  5. Action redirects or returns errors
  6. Loader refetches data
  7. Component renders updated state

Key Design Decisions

Why Single Table DynamoDB?

We use single table design because:

  • Lower costs (one table vs many)
  • Better performance (no joins needed)
  • Atomic transactions across entities
  • Aligns with serverless architecture

See: docs/dynamodb-design.md

Why SST over CDK?

  • Type-safe resource bindings
  • Better developer experience
  • Simpler infrastructure code
  • Great local development story
  1. Setup Documentation

Make it easy for new developers:

Setup Guide

Prerequisites

  • Node.js 20+
  • AWS account with CLI configured
  • GitHub account (for deployment)

Installation

  1. Clone the repository: ```bash git clone https://github.com/your-org/project cd project ```

  2. Install dependencies: ```bash npm install ```

  3. Set up environment: ```bash cp .env.example .env

    Edit .env and add your values

    ```

  4. Start SST: ```bash npm run sst:dev ```

  5. In another terminal, start Remix: ```bash npm run dev ```

  6. Visit http://localhost:3000

Troubleshooting

"Cannot find module 'sst'"

Run npm install again. SST might not have installed correctly.

Port 3000 already in use

Kill the process using port 3000 or change the port in package.json.

  1. ADR (Architecture Decision Records)

Document important decisions:

ADR 001: Use Single Table Design for DynamoDB

Status

Accepted

Context

We need to store users, posts, comments, and relationships between them. Traditional approach would be separate tables, but we're building a serverless app.

Decision

We will use single table design with generic pk/sk keys.

Consequences

Positive

  • Lower costs (one table vs many)
  • Better query performance (no joins)
  • Atomic transactions across entity types
  • Simpler infrastructure

Negative

  • Higher initial learning curve
  • Requires understanding access patterns upfront
  • More complex to query during development

Alternatives Considered

  • Multiple tables (rejected: higher costs, no cross-table transactions)
  • Relational DB (rejected: doesn't fit serverless model well)

Documentation Patterns

Pattern 1: Tutorial-Style Guides

Walk through a complete example:

Building Your First Feature

Let's build a simple blog post feature together.

Step 1: Create the Database Schema

First, we'll define how posts are stored in DynamoDB.

A post has:

  • ID (unique identifier)
  • Author (user who created it)
  • Title
  • Content
  • Created date

In single table design, we'll store this as:

```typescript { pk: "POST#<postId>", sk: "METADATA", authorId: "<userId>", title: "My First Post", content: "Hello, world!", createdAt: "2025-01-02T10:00:00Z" } ```

Step 2: Create the Route

Create a new file: app/routes/posts.new.tsx

```typescript // ... code here ```

Step 3: Add the Form

// ... continue the tutorial

Pattern 2: Reference Documentation

Quick lookup for APIs:

Database API Reference

createPost()

Creates a new blog post.

Signature: ```typescript createPost(authorId: string, data: PostData): Promise<Post> ```

Parameters:

  • authorId - ID of the user creating the post
  • data.title - Post title (required, max 200 chars)
  • data.content - Post content (required, max 50000 chars)

Returns:

  • Promise resolving to created Post object

Throws:

  • ValidationError - If data is invalid
  • DatabaseError - If write fails

Example: ```typescript const post = await createPost("user123", { title: "Hello World", content: "My first post!" }); ```

Pattern 3: Troubleshooting Guides

Help users solve common problems:

Troubleshooting Guide

Common Issues

SST Deploy Fails with "Resource already exists"

Symptoms: ``` Error: Resource MyFunction already exists ```

Cause: A previous deployment failed partway through.

Solution:

  1. Delete the CloudFormation stack manually: ```bash aws cloudformation delete-stack --stack-name my-app-dev ```
  2. Wait for deletion to complete
  3. Deploy again: npm run deploy

DynamoDB Query Returns No Results

Symptoms: Query runs without errors but returns empty array.

Common Causes:

  1. Wrong key format - Check your pk/sk format matches
  2. Using scan instead of query - Use Query for single partition
  3. GSI not ready - Wait a few seconds after creating items

Debug Steps:

  1. Log the query parameters
  2. Check item in DynamoDB console
  3. Verify key format matches exactly

Best Practices

  1. Keep Docs Close to Code

src/ lib/ email/ send.ts README.md # Email system docs examples.md # Usage examples

  1. Use Markdown Formatting

Headers for sections

Subheaders for subsections

Bold for emphasis Italic for terms

code for inline code ```typescript // code blocks ```

Blockquotes for notes

  • Bullet lists
  • For multiple items
  1. Numbered lists

  2. For sequential steps

  3. Include Code Examples

Always show working code:

Creating a User

```typescript import { createUser } from "./lib/users";

const user = await createUser({ email: "user@example.com", password: "secure123", name: "John Doe" });

console.log(Created user: ${user.id}); ```

  1. Link Related Documentation

See also:

  1. Keep It Current

<!-- Add a "Last Updated" note -->

Last Updated: 2025-01-02 Version: 2.0.0

Documentation Tools

JSDoc for TypeScript

/**

  • Represents a blog post. / export interface Post { /* Unique identifier */ id: string;

/** Post title (max 200 characters) */ title: string;

/** Post content in Markdown format */ content: string;

/** ISO 8601 timestamp of creation */ createdAt: string;

/** ID of the author */ authorId: string; }

README Badges

Build Status Coverage License

Diagrams with Mermaid

```mermaid graph TD A[User submits form] --> B[Remix action] B --> C{Valid data?} C -->|Yes| D[Save to DB] C -->|No| E[Return errors] D --> F[Redirect to success] E --> G[Show form with errors] ```

Documentation Checklist

When documenting a new feature:

  • Update README if user-facing

  • Add JSDoc comments to public APIs

  • Create usage examples

  • Document configuration options

  • Explain error messages

  • Add troubleshooting tips

  • Link to related docs

  • Update architecture diagrams

  • Review for clarity

  • Test all code examples

Common Mistakes to Avoid

❌ Don't:

  • Write docs that are out of date

  • Use jargon without explanation

  • Skip error handling in examples

  • Document internal implementation details

  • Write novels (keep it concise)

  • Assume prior knowledge

✅ Do:

  • Update docs with code changes

  • Define terms on first use

  • Show how to handle errors

  • Document public APIs and behavior

  • Be clear and direct

  • Provide context and examples

Documentation as Code

Treat docs like code:

// docs/examples/create-user.test.ts // This file is both docs and tests!

import { createUser } from "../src/lib/users";

test("creating a user", async () => { // This example appears in docs const user = await createUser({ email: "user@example.com", password: "secure123", name: "John Doe" });

expect(user.email).toBe("user@example.com"); expect(user.name).toBe("John Doe"); });

Further Reading

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

frontend-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

email-templates

No summary provided by upstream source.

Repository SourceNeeds Review
General

marketing-copy

No summary provided by upstream source.

Repository SourceNeeds Review
General

conform

No summary provided by upstream source.

Repository SourceNeeds Review