Why Documentation Is Not a Boring Obligation, But a Developer's Superpower
\n\nImagine: you open someone else's (or your own from three months ago) JavaScript project. Files are full of arrow functions, async/await, and destructuring. But why is this function called transformData? What does it accept? And most importantly — why is it needed if there's also processArray?
If you've ever caught yourself thinking, "I don't remember what's happening here," — this article is for you. Documentation in JavaScript is not about boring paragraphs of text. It's about respect for your future self and your colleagues. It's about speeding up project onboarding and reducing the number of bugs. In this article, we'll break down the best practices for documenting JS code: from JSDoc to generating full-fledged documentation.
\n\nJavaScript Code Documentation: The Philosophy of "Self-Documenting Code"
\n\nBefore writing comments, it's important to understand: the best comment is the one that isn't needed. Ideal code should explain itself. How to achieve this?
\n\nNaming Variables and Functions
\nBad example:
\n// Bad\nconst x = 10; // what is x?\nfunction d(a, b) { return a * b; } // what does d do?\n\nGood example:
\n// Good\nconst MAX_RETRY_COUNT = 10;\nfunction calculateDiscountedPrice(price, discountPercent) {\n return price * (1 - discountPercent / 100);\n}\n\nUse full, meaningful names. Name functions with verbs (getUser, validateEmail), and variables with nouns (userList, isActive). This is the foundation of self-documenting code.
When Comments Are Still Necessary
\n- \n
- Complex business logic: for example, calculating taxes using a non-obvious formula. \n
- A hack or temporary solution: mark it with
TODOorFIXME. \n - Why a particular approach was chosen: alternatives existed, but this one is optimal in terms of speed. \n
- Describing a public API: so other developers know how to call your function. \n
JSDoc: The JavaScript Documentation Standard
\nJSDoc is a syntax for writing documentation directly in the code, which is understood by editors (VS Code, WebStorm) and generation tools. It's a must-have for any serious project.
\n\nBasic Function Annotation
\n/**\n * Calculates the total order cost including discount and tax.\n * @param {number} price - The base price of the item.\n * @param {number} discount - Discount percentage (0-100).\n * @param {number} taxRate - Tax rate percentage (0-100).\n * @returns {number} The total cost.\n */\nfunction calculateTotal(price, discount, taxRate) {\n const discountedPrice = price * (1 - discount / 100);\n return discountedPrice * (1 + taxRate / 100);\n}\n\nNow, when you hover over the calculateTotal function in the editor, you'll see its description, parameters, and return value. Magic!
Annotations for Objects and Types
\n/**\n * @typedef {Object} User\n * @property {number} id - Unique identifier.\n * @property {string} name - User's name.\n * @property {boolean} isActive - Whether the account is active.\n */\n\n/**\n * Gets a list of active users.\n * @param {User[]} users - Array of users.\n * @returns {User[]} Filtered array.\n */\nfunction getActiveUsers(users) {\n return users.filter(user => user.isActive);\n}\n\nUsing @typedef allows you to create custom types, making the code readable and safe. This is especially useful in projects without TypeScript.
Documenting Async Functions
\n/**\n * Loads user data from the server.\n * @async\n * @param {number} userId - User ID.\n * @returns {Prom