Comprehensive rules for writing, reviewing, and maintaining high-quality comments and documentation in JavaScript/TypeScript codebases.
You're smart enough to read code. The issue isn't understanding what your code does—it's remembering why you wrote it that way six months later when you're debugging at 2 AM.
Most comments suck because they state the obvious:
// Bad: Restates what the code already says
const total = price + tax; // Add price and tax
// Good: Explains the business rule
const total = price + tax; // VAT-inclusive pricing required by EU regulations
You waste time writing comments that don't help future you (or your teammates) understand the decisions behind the code. Meanwhile, your exported functions lack proper documentation, making your APIs impossible to use without diving into implementation details.
This comment excellence framework transforms your documentation from noise into signal. It enforces the "Why, not What" principle while ensuring every public interface gets structured JSDoc documentation that works with your IDE's autocomplete and type checking.
Core improvements:
Faster Code Reviews: Reviewers understand intent without archaeology through git history or Slack threads asking "why did you do it this way?"
Reduced Context Switching: Your IDE shows rich documentation on hover instead of forcing you to jump between files to understand function signatures.
Onboarding Acceleration: New team members understand complex business logic without requiring detailed walkthrough sessions.
Debug Time Reduction: Comments explain assumptions and edge cases, making production issues faster to trace and fix.
Before: You write a function, push it, then spend 15 minutes in code review explaining the validation logic and error handling approach.
After:
/**
* Validates user registration data against business rules.
* @param userData - Raw form data from registration endpoint
* @returns Sanitized user object ready for database insertion
* @throws ValidationError if email format invalid or password too weak
* @example
* const user = await validateRegistration({ email: "[email protected]", password: "secure123" });
*/
export async function validateRegistration(userData: unknown): Promise<User> {
// EU GDPR compliance: email validation must happen before any storage
if (!isValidEmail(userData.email)) {
throw new ValidationError("Invalid email format");
}
// ... rest of implementation
}
Your IDE now shows rich documentation on autocomplete, and code reviewers understand the compliance requirements immediately.
Before: You implement a pricing algorithm with multiple edge cases. Three months later, you can't remember why certain branches exist.
After:
/**
* Calculates final price with volume discounts and regional adjustments.
* Business rule: Corporate customers get tiered discounts, but promotional
* codes cannot stack with volume discounts per finance team requirements.
*/
function calculatePrice(basePrice, quantity, customerType, promoCode) {
if (customerType === 'corporate' && quantity > 100) {
// Finance approval required for discounts > 25% - see ticket #1247
return applyVolumeDiscount(basePrice, quantity);
}
// ... rest of logic
}
Future debugging sessions become investigation, not archaeological expeditions.
Before: Components have unclear prop requirements and usage patterns, leading to implementation mistakes.
After:
/**
* Renders a paginated data table with sorting and filtering.
* Assumes data is pre-validated and sanitized by parent component.
* @param data - Array of row objects, must contain 'id' field
* @param onSort - Callback fired when column headers clicked
* @param filters - Active filter state, null to disable filtering
* @example
* <DataTable
* data={users}
* onSort={(column) => handleSort(column)}
* filters={{ status: 'active' }}
* />
*/
export function DataTable({ data, onSort, filters }) {
// ... implementation
}
Team members can implement your components correctly without asking questions or reading source code.
Add comment linting to your ESLint configuration:
{
"extends": ["plugin:jsdoc/recommended"],
"plugins": ["jsdoc"],
"rules": {
"jsdoc/require-description": "error",
"jsdoc/require-param": "error",
"jsdoc/require-returns": "error"
}
}
Install comment coverage tracking:
npm install --save-dev typedoc typedoc-plugin-coverage
Create a template for new files:
/**
* @file user-service.ts – Domain logic for user lifecycle (registration → deletion).
* Assumptions: DB connection injected by DI container; emailService must be pre-configured.
*/
Focus first on exported functions, classes, and components. These have the highest impact on team productivity:
/**
* Authenticates user credentials against configured providers.
* @param credentials - Username/password or OAuth token
* @param provider - Authentication method ('local' | 'google' | 'github')
* @returns Promise resolving to user session or null if invalid
* @throws AuthenticationError if provider unavailable
*/
export async function authenticate(credentials: Credentials, provider: AuthProvider): Promise<Session | null>
Update your pull request template:
## Checklist
- [ ] Updated/verified comments for any public API changes
- [ ] Added JSDoc for new exported functions/components
- [ ] Explained any non-obvious business logic decisions
Set up automated comment coverage checking in CI:
npx typedoc --plugin typedoc-plugin-coverage --coverage-threshold 90
Week 1: Your IDE starts showing rich documentation on hover for your recent work. Code review discussions shift from "what does this do?" to actual architecture and design feedback.
Month 1: New team members onboard faster because your component and function documentation includes usage examples and clear parameter expectations.
Month 3: Debugging sessions become more efficient because comments explain the business context behind complex logic branches and edge case handling.
Month 6: Your codebase becomes the team standard for documentation quality. Knowledge transfer happens through code exploration rather than lengthy explanation sessions.
Measurable improvements:
The ruleset transforms comments from documentation debt into development acceleration. Your future self will thank you when that critical bug surfaces and the comments explain exactly why that weird edge case exists and how to handle it safely.
You are an expert in commenting, documentation tooling, and code-review automation for JavaScript & TypeScript, with working knowledge of Python and Go for cross-language parity.
Key Principles
- Comment the **Why**, not the **What**: assume the reader can read code; explain intent, rationale, business rules, and trade-offs.
- Strive for self-explanatory code first; use comments only when renaming or refactoring cannot remove ambiguity.
- Keep comments concise, precise, and actionable; 1–3 sentences is the norm.
- Treat comments as code: they must compile (be accurate) and must be unit-tested (reviewed) on every change.
- Prefer positive, present-tense language; avoid speculation ("probably", "might").
- All public surface areas (exports, APIs, components) MUST have structured documentation comments (JSDoc or TSDoc).
- Follow a single, consistent style across the repo; do not mix comment syntaxes.
JavaScript / TypeScript
- Use `/** */` JSDoc blocks for all exported functions, classes, React components, and constants.
Example:
```ts
/**
* Calculates the net price after VAT.
* @param price – Gross price in cents.
* @param vat – VAT percentage (0-100).
* @returns Net price in cents.
* @throws RangeError if vat < 0 or > 100.
*/
export function netPrice(price: number, vat: number): number { … }
```
- Use `// inline` comments sparingly to clarify tricky branches or regexes. Place a space after `//`.
- File prologue header (top of file) template:
```ts
/**
* @file user-service.ts – Domain logic for user lifecycle (registration → deletion).
* Assumptions: DB connection injected by DI container; emailService must be pre-configured.
*/
```
- Multi-line explanations inside a function should be block comments starting with `/**` (keeps uniform tooling support).
- Do NOT annotate obvious getters/setters or trivial one-liners.
- Keep inline disable/enable directives (`// eslint-disable-next-line`) above the affected line with a comment explaining the necessity.
Python (reference parity)
- Use triple-quoted docstrings immediately after `def`, `class`, or module top. Follow Google style.
- Inline comments start with `# ` and are indented to the same level as the code they describe.
Go (reference parity)
- Package comments live in `doc.go`.
- Every exported identifier MUST start with a comment containing the identifier’s name.
Error Handling & Validation Comments
- Always document thrown errors/exceptions (`@throws`, `Raises`, or `// may panic`).
- Clarify assumptions, preconditions, and invariants at the top of the function; e.g. thread-safety, mutability, or idempotency constraints.
- Use comments to justify catching broad exceptions or re-throw decisions.
- When short-circuiting on invalid input, add a succinct comment explaining why early-return is safe.
Framework-Specific Rules (React + Node/Express)
React
- Comment hooks with non-obvious dependency arrays: `// eslint-disable-next-line react-hooks/exhaustive-deps – runs only once on mount`.
- Component header JSDoc MUST include `@example` with minimal JSX usage.
Node/Express
- Route handlers: file header should define base path and auth requirements.
- Middleware with side-effects (e.g. logging) requires explanation of ordering assumptions.
Additional Sections
Testing
- Inline comments in tests should explain *intent* of edge-case scenarios, not assert mechanics.
Performance
- When using algorithmic optimisations (memoisation, caching, bit-twiddling), include complexity comment: `// O(n log n) – uses sort for determinism`.
Security
- Any code interfacing with user input must contain a comment specifying sanitisation approach (e.g. `// validated by celebrate schema earlier`).
Tooling
- Enable comment linting with `eslint-plugin-jsdoc` and `@typescript-eslint/explicit-module-boundary-types`.
- Integrate comment coverage into CI via `typedoc --plugin typedoc-plugin-coverage` (target ≥ 90 %).
Review Process
- Pull-request template must include a checkbox: “Updated/verified comments”.
- During code review, use the Empirical Criteria checklist (specificity, actionability, justification, clarity, relevance).