JSDoc
JSDoc is an API documentation generator for JavaScript that enables developers to create detailed, structured documentation by embedding special comments directly within their source code.[1] These comments follow a standardized syntax inspired by Javadoc, using block-level tags such as @param, @returns, and @type to describe functions, methods, parameters, return values, and other code elements.[1] The tool processes annotated JavaScript files via a command-line interface and outputs professional HTML documentation, often resembling a static website with navigation, search capabilities, and cross-references.[1]
Originally developed as a JavaScript-based tool starting in 2011 by Michael Mathews, JSDoc builds on earlier documentation practices for JavaScript.[2] The project, hosted on GitHub under the Apache License 2.0, has evolved through community contributions and now supports modern JavaScript features including ES6+ modules, async functions, and TypeScript-like type annotations.[2] As of November 2025, the latest stable release is version 4.0.5, compatible with Node.js 12.0.0 and later, and it includes plugins for extensions like Markdown formatting and custom templates.[3]
Beyond basic documentation, JSDoc enhances code maintainability by facilitating tools like IDE autocompletion and type checking in environments such as TypeScript, where JSDoc annotations serve as a bridge for adding type information to plain JavaScript files.[4] It is widely adopted in open-source projects and enterprise settings for generating readable API references, with configurable options for output formats, source parsing, and integration with build tools like Webpack or Gulp. This makes JSDoc a foundational tool in the JavaScript ecosystem, promoting self-documenting code without requiring a separate type system.[2]
Introduction
Purpose and Scope
JSDoc is an API documentation generator for JavaScript, designed to create structured documentation by embedding special comment blocks directly into source code.[1] It functions similarly to tools like Javadoc or phpDocumentor, allowing developers to annotate elements such as modules, namespaces, classes, methods, and parameters within their JavaScript files.[1]
The scope of JSDoc centers on annotating JavaScript source code to generate comprehensive API documentation, while also supporting advanced features like IDE autocompletion through IntelliSense and enabling static type analysis.[1][5][4] By parsing these annotations, JSDoc produces output in formats such as HTML websites, which detail the application's interface and behavior without requiring separate documentation files.[1]
Primary applications of JSDoc include generating navigable HTML documentation sites for JavaScript projects, enhancing code readability through inline explanations, and promoting team collaboration by standardizing documentation practices that reduce misunderstandings and onboarding time.[1][6] JSDoc emerged to fulfill the need for structured documentation in dynamic languages like JavaScript, where traditional type systems are absent.[1]
Key Features
JSDoc enables the addition of type annotations directly within JavaScript comments, allowing developers to specify types for variables, parameters, returns, and more using tags such as @type, @param, and @typedef. This feature facilitates static type checking when integrated with tools like the Google Closure Compiler, which interprets these annotations to detect type errors and optimize code during compilation.[7][8]
One of JSDoc's core strengths is its ability to generate structured documentation outputs from inline comments, producing formats such as HTML websites, JSON data, or Markdown files. By running the JSDoc command-line tool on source code, it automatically parses comments and renders them into navigable documentation, with customizable templates to tailor the presentation for project needs.[1][9]
JSDoc offers extensibility through the creation of custom tags and templates, enabling users to define project-specific documentation elements via plugins or configuration files. For instance, developers can implement new tags to handle domain-specific annotations, and modify output templates to integrate with various publishing systems, ensuring adaptability to diverse workflows.[9][10]
The tool maintains compatibility with modern JavaScript standards, including ES6 and later features such as classes, modules, async functions, and generics, allowing seamless documentation of contemporary code patterns without requiring syntax adjustments.[11]
Furthermore, JSDoc integrates effectively with TypeScript environments, where its type annotations can be used in JavaScript files to leverage TypeScript's type checking and IntelliSense while generating documentation that aligns with TypeScript's syntax, supporting hybrid projects that mix typed and untyped code.[4]
History and Development
Origins and Early Versions
JSDoc's development began with JSDoc.pm, a simple Perl-based system created by Michael Mathews in 2001.[2] The project evolved with the release of JsDoc Toolkit (version 2.0) in 2008, drawing inspiration from JavaDoc's approach to generating API documentation from code comments.[2] This iteration addressed the challenges of documenting dynamically typed languages like JavaScript, where built-in type information and formal documentation were absent, allowing developers to embed structured comments directly in source code to produce readable HTML outputs.[12]
The modern incarnation, JSDoc 3, saw its initial release in 2011, licensed under the Apache License 2.0, which facilitated broader adoption by permitting both commercial and non-commercial use while ensuring compatibility with open-source practices.[2] Primarily motivated by the need to provide maintainable documentation for growing JavaScript applications, particularly in server-side environments, it emphasized simplicity in comment-based annotation over complex tooling.[1]
Early adoption was prominent within the Node.js community, where JSDoc proved valuable for documenting CommonJS modules and APIs in backend projects, helping standardize documentation amid the rapid expansion of server-side JavaScript in the early 2010s.[13]
Around 2012, the project transitioned to a fully community-driven effort on GitHub, with key early contributors who enhanced parsing and template features, solidifying its role as a collaborative open-source initiative.[14] This shift marked a pivotal point, enabling ongoing improvements while maintaining Mathews' foundational vision, before major evolutions in later versions.
Major Releases and Evolution
JSDoc 3.0.0 marked a significant milestone when it was released in May 2012, introducing a robust template system that enabled developers to customize documentation output formats and layouts, moving beyond the rigid structures of earlier versions. This release laid the foundation for modern JSDoc by supporting inline documentation parsing and generating HTML-based API references, fostering greater adoption in JavaScript projects.[15]
Subsequent updates in the 3.x series enhanced language feature support, with version 3.4.0 in November 2015 adding parsing for ES2015 classes and modules, including initial JSX handling, which improved compatibility with emerging JavaScript standards. Version 3.5.0, released in July 2017, integrated the Babylon parser to provide comprehensive ES2015+ support, including async/await and generator functions, along with new tags like @async and @generator to better document asynchronous code patterns. These changes addressed key pain points in documenting modern JavaScript, boosting JSDoc's utility in Node.js environments requiring Node.js 4.2.0 or later.[15]
Version 3.6.0, released in May 2019, further refined these capabilities with enhanced ES2015 class documentation and compatibility for Closure Compiler annotations, enabling stricter typing similar to TypeScript through tags like @typedef and @enum for more precise type expressions. This update also introduced configuration options like templates.useShortNamesInLinks for cleaner output and improved plugin extensibility, making JSDoc more adaptable for large-scale projects. By 2020, these enhancements solidified JSDoc's role in hybrid JavaScript/TypeScript workflows, where developers could leverage TypeScript-like type annotations without full compilation.[15]
The transition to JSDoc 4.0.0 in November 2022 represented a major evolutionary step, adopting semantic versioning to standardize release cycles and dependency management, while removing the legacy taffydb for better performance and requiring Node.js 12.0.0 or later. This version emphasized modularity and efficiency in the plugin ecosystem, allowing easier extension for custom parsers and themes. As of November 2025, the latest stable release is 4.0.5 from October 2025, which includes bug fixes for compatibility with Node.js 23 and optimizations in parsing speed, contributing to broader adoption in performance-sensitive applications.[15][3]
Throughout its evolution, JSDoc has benefited from active community involvement on GitHub, where numerous pull requests have driven features like advanced type handling and runtime integrations. Community efforts have extended JSDoc to modern runtimes, including experimental support for Deno and Bun through custom configurations and plugins that adapt its Node.js-based parsing to these environments.[2][16]
Syntax Fundamentals
JSDoc documentation comments are exclusively block comments that begin with the sequence /** and end with */, distinguishing them from standard JavaScript multi-line comments starting with /* or single-line comments using //.[1] The /** format ensures that the JSDoc parser recognizes and processes the comment for generating documentation, whereas // comments are treated as ordinary inline annotations without structured parsing support in JSDoc.[1]
The required structure of a JSDoc comment starts with the opening /**, followed by optional leading asterisks on subsequent lines for readability, a descriptive text block that provides an overview of the documented symbol, and then optional block tags prefixed with @ on separate lines.[1] The descriptive text precedes any tags and can span multiple lines, while the closing */ must appear on its own line after all content.[17] This format allows for a hierarchical organization where the main description sets the context, and tags add metadata without interrupting the narrative flow.
Placement conventions dictate that JSDoc comments must appear immediately preceding the code symbol they document, such as a function declaration, class definition, variable assignment, or property in an object literal, to associate the documentation correctly during parsing.[1] For instance, the comment block should have no intervening code or whitespace between it and the target symbol, ensuring unambiguous linking in the generated output.[1]
Nesting rules permit JSDoc comments within complex structures like classes or objects, where individual comments can document inner members such as methods or properties by placing a /** block directly before each one.[1] This approach supports hierarchical documentation without requiring a single encompassing comment for the entire structure, though outer comments can provide overarching descriptions while inner ones focus on specifics.[18]
Avoid using sequences like */ in descriptions, as they will prematurely terminate the comment. For curly braces in inline tags embedded within the text, a closing brace (}) must be escaped as \{ to include it verbatim.[17] Asterisks (*) can generally appear literally in descriptive text as long as they do not form tag delimiters. Avoid starting lines with @ for literal text outside of tags, as it may be parsed as a block tag; use indentation, spaces before @, or restructure the text to avoid issues.[17]
The following example illustrates the basic structure and placement for a function, with descriptive text and optional tag lines:
/**
* This [function](/page/Function) processes input [data](/page/Data).
* It handles validation and transformation.
*
* @param {string} input - The [data](/page/Data) to process.
* @returns {[boolean](/page/Boolean)} Success indicator.
*/
[function](/page/Function) processData(input) {
// [Implementation](/page/Implementation) here
}
```[](https://jsdoc.app/about-getting-started)
### Basic Tag Syntax
JSDoc [tags](/page/Tag) provide structured [metadata](/page/Metadata) within [documentation](/page/Documentation) comments, following a consistent syntax to ensure reliable [parsing](/page/Parsing) and generation of [documentation](/page/Documentation). The basic format for a block [tag](/page/Tag) is `@tagname [optional description or parameters]`, where the tag name begins with an `@` symbol, optionally followed by type information, identifiers, and a descriptive text separated by a [hyphen](/page/Hyphen) or [space](/page/Space). This structure allows [tags](/page/Tag) to annotate elements like [functions](/page/Function), parameters, or returns, with the [description](/page/Description) providing additional context about usage or behavior.[](https://jsdoc.app/about-block-inline-tags)
Type expressions in JSDoc are enclosed in curly braces `{}` to denote the data type precisely, enhancing type checking and IDE support. For instance, simple types use `{string}` or `{number}`, while complex types employ notations like `{Array.<number>}` for arrays of numbers or `{Object.<string, boolean>}` for objects with string keys and boolean values. Inline tags, which embed annotations within descriptions, follow the pattern `{@tag value}`, such as `{@type string}` to specify a type mid-sentence. These curly brace conventions draw from Closure Compiler annotations, integrated into JSDoc since version 3.2, to support advanced type expressions including unions like `{(number|string)}`, nullable types `{?number}`, and non-nullable `{!number}`.[](https://jsdoc.app/tags-type)[](https://jsdoc.app/tags-type)
Multi-line tags are handled by continuing the description on subsequent lines within the comment block, without additional markers, while separate tags require line breaks after each `@tagname` declaration. For extended descriptions, the content flows naturally until the next tag or the block's end, allowing for detailed explanations without breaking the structure. If a tag spans multiple lines, JSDoc parses it as a single unit, preserving formatting for [readability](/page/Readability) in generated output.[](https://jsdoc.app/about-block-inline-tags)
While JSDoc supports legacy formats, such as `@param` without curly braces for types (e.g., `@param name - description`), this older syntax is discouraged as it omits type information, reducing the effectiveness of tools like static analyzers and [IDE](/page/IDE) autocompletion. Modern practice mandates including types in braces for parameters and similar tags to leverage full [type inference](/page/Type_inference) capabilities.[](https://jsdoc.app/tags-param)
Malformed tags, such as unclosed curly braces or invalid type expressions, trigger [parsing](/page/Parsing) errors during JSDoc processing, potentially halting [documentation](/page/Documentation) generation or producing incomplete output. To mitigate this, the `--lenient` command-line option downgrades type-related errors to warnings, allowing [parsing](/page/Parsing) to continue while flagging issues for correction. Proper syntax adherence ensures robust handling across parsers and integrations.[](https://jsdoc.app/tags-type)
## Core Tags and Annotations
### Parameter and Return Tags
The `@param` [tag](/page/Tag) is used to document the [parameter](/page/Parameter)s of a [function](/page/Function), specifying the name, type, and description for each input argument. Its basic syntax is `@param {type} parameterName - description`, where the type is enclosed in curly braces and is optional, the parameter name is required, and the description follows a [hyphen](/page/Hyphen) for readability.[](https://jsdoc.app/tags-param) This [tag](/page/Tag) supports aliases such as `@arg` and `@argument`, which [function](/page/Function) identically to `@param`.[](https://jsdoc.app/tags-param)
For optional parameters, the name can be enclosed in square brackets, as in `@param {string} [optionalName] - An optional string value`, indicating the argument can be omitted. Default values are documented by including them within the brackets, for example, `@param {number} [count=1] - Number of items, defaults to 1`. Variadic parameters, representing rest arguments, are denoted with ellipsis notation like `@param {...string} items - Variable number of string items`. Union types for parameters that accept multiple possible types are expressed using the pipe operator, such as `@param {string|number} value - A value that can be a string or number`; these type expressions follow the syntax detailed in the type documentation.[](https://jsdoc.app/tags-param)
The `@returns` tag documents the value returned by a function, with the syntax `@returns {type} description`, where the type is optional and the description provides context about the output. It accepts aliases like `@return`, which behaves the same way. For functions that return nothing, the type can be omitted or specified as `{void}`; asynchronous functions commonly use `@returns {Promise<type>}` to indicate a promised result, such as `@returns {Promise<string>} A resolved string value`. Union types are also supported here, e.g., `@returns {number|string} Either a number or string`.[](https://jsdoc.app/tags-returns)
These tags are particularly valuable for documenting overloaded functions, where multiple sets of `@param` and `@returns` tags describe each possible signature, enabling clear [API](/page/API) documentation for polymorphic behaviors. In asynchronous contexts, combining `@returns` with [Promise](/page/Promise) types ensures generated documentation reflects modern [JavaScript](/page/JavaScript) patterns like async/await.[](https://jsdoc.app/tags-param)[](https://jsdoc.app/tags-returns)
### Type and Property Tags
The [@type](/page/type) tag in JSDoc allows developers to specify the [data type](/page/Data_type) of a [variable](/page/Variable), [property](/page/Property), or return value, enhancing [code](/page/Code) readability and enabling tools like type checkers to infer types accurately.[](https://jsdoc.app/tags-type) This tag supports a wide range of type expressions, including primitives like `{string}` or `{number}`, as well as more complex constructs such as unions `{number|string}`, making it essential for documenting dynamic [JavaScript](/page/JavaScript) code in a type-safe manner.[](https://jsdoc.app/tags-type)
For object literals and interfaces, the @property tag (or its synonym @prop) documents individual members of an object, specifying their types and descriptions within the context of a [class](/page/Class), [namespace](/page/Namespace), or [typedef](/page/Typedef).[](https://jsdoc.app/tags-property) The syntax follows `@property {type} name - description`, where the type can reference primitives or custom definitions, and optional properties are denoted with square brackets, such as `@property {string} [nickname] - Optional user nickname`.[](https://jsdoc.app/tags-property) This tag is particularly useful for listing static properties without defining actual code, ensuring comprehensive documentation for object structures.[](https://jsdoc.app/tags-property)
To create reusable custom type aliases, the @typedef tag defines named types that can be referenced elsewhere, promoting consistency across documentation.[](https://jsdoc.app/tags-typedef) Its syntax is `@typedef {type} name`, as in `/** @typedef {(number|string)} NumberLike */`, which can then be used in other tags like `@type {NumberLike} value`.[](https://jsdoc.app/tags-typedef) Complex types defined via @typedef often incorporate @property for detailing object members, such as `/** @typedef {Object} User @property {string} name @property {number} age */`, allowing for intricate data models without redundant declarations.[](https://jsdoc.app/tags-typedef)
JSDoc's type system supports advanced expressions for common scenarios, including nullable types with `?` (e.g., `{?string}` for string or null), arrays via `[type]` or `Array.<type>` (e.g., `{string[]}`), and function types like `{function(string, number): boolean}` to describe signatures precisely.[](https://jsdoc.app/tags-type) These constructs, rooted in Google Closure Compiler compatibility, enable detailed type annotations such as record types `{Object.<string, boolean>}` for key-value mappings.[](https://jsdoc.app/tags-type)
For integrating with third-party libraries, the @external tag marks symbols from external sources, allowing their types to be referenced without full redefinition, such as `@external [String](/page/String)` followed by extensions like `@method {function(): string} [rot13](/page/ROT13)`.[](https://jsdoc.app/tags-external) This facilitates documentation of interactions with libraries like [jQuery](/page/JQuery) or browser APIs, using prefixes like `external:XMLHttpRequest` in links or inheritance tags.[](https://jsdoc.app/tags-external) Such types can be employed in @param tags for [function](/page/Function) arguments, as detailed in the Parameter and Return Tags section.[](https://jsdoc.app/tags-type)
## Advanced Usage
### Module and Namespace Tags
In large [JavaScript](/page/JavaScript) projects, [module](/page/Module) and [namespace](/page/Namespace) tags in JSDoc enable developers to organize and [document](/page/Documentation) code structures that group related symbols, facilitating better navigation and understanding in generated [documentation](/page/Documentation). These tags are particularly essential for modular architectures, where code is divided into self-contained units that [export](/page/Export) specific members while hiding [implementation](/page/Implementation) details. By declaring [modules](/page/Module) and namespaces explicitly, JSDoc can generate hierarchical [documentation](/page/Documentation) that reflects the project's organization, often using namepaths prefixed with "module:" for cross-references.[](https://jsdoc.app/tags-module)
The [@module](/page/Module) tag declares the current [file](/page/File) as a module, treating all symbols within it as module members unless overridden. Its syntax is `@module [[{<type>}] <moduleName>]`, where the optional type expression (such as `{Object}`) specifies the module's type, and the name identifies the module for referencing; in JSDoc 3.3.0 and later, the name can include a "module:" prefix. For example:
/**
* This [function](/page/Function) processes input [data](/page/Data).
* It handles validation and transformation.
*
* @param {string} input - The [data](/page/Data) to process.
* @returns {[boolean](/page/Boolean)} Success indicator.
*/
[function](/page/Function) processData(input) {
// [Implementation](/page/Implementation) here
}
```[](https://jsdoc.app/about-getting-started)
### Basic Tag Syntax
JSDoc [tags](/page/Tag) provide structured [metadata](/page/Metadata) within [documentation](/page/Documentation) comments, following a consistent syntax to ensure reliable [parsing](/page/Parsing) and generation of [documentation](/page/Documentation). The basic format for a block [tag](/page/Tag) is `@tagname [optional description or parameters]`, where the tag name begins with an `@` symbol, optionally followed by type information, identifiers, and a descriptive text separated by a [hyphen](/page/Hyphen) or [space](/page/Space). This structure allows [tags](/page/Tag) to annotate elements like [functions](/page/Function), parameters, or returns, with the [description](/page/Description) providing additional context about usage or behavior.[](https://jsdoc.app/about-block-inline-tags)
Type expressions in JSDoc are enclosed in curly braces `{}` to denote the data type precisely, enhancing type checking and IDE support. For instance, simple types use `{string}` or `{number}`, while complex types employ notations like `{Array.<number>}` for arrays of numbers or `{Object.<string, boolean>}` for objects with string keys and boolean values. Inline tags, which embed annotations within descriptions, follow the pattern `{@tag value}`, such as `{@type string}` to specify a type mid-sentence. These curly brace conventions draw from Closure Compiler annotations, integrated into JSDoc since version 3.2, to support advanced type expressions including unions like `{(number|string)}`, nullable types `{?number}`, and non-nullable `{!number}`.[](https://jsdoc.app/tags-type)[](https://jsdoc.app/tags-type)
Multi-line tags are handled by continuing the description on subsequent lines within the comment block, without additional markers, while separate tags require line breaks after each `@tagname` declaration. For extended descriptions, the content flows naturally until the next tag or the block's end, allowing for detailed explanations without breaking the structure. If a tag spans multiple lines, JSDoc parses it as a single unit, preserving formatting for [readability](/page/Readability) in generated output.[](https://jsdoc.app/about-block-inline-tags)
While JSDoc supports legacy formats, such as `@param` without curly braces for types (e.g., `@param name - description`), this older syntax is discouraged as it omits type information, reducing the effectiveness of tools like static analyzers and [IDE](/page/IDE) autocompletion. Modern practice mandates including types in braces for parameters and similar tags to leverage full [type inference](/page/Type_inference) capabilities.[](https://jsdoc.app/tags-param)
Malformed tags, such as unclosed curly braces or invalid type expressions, trigger [parsing](/page/Parsing) errors during JSDoc processing, potentially halting [documentation](/page/Documentation) generation or producing incomplete output. To mitigate this, the `--lenient` command-line option downgrades type-related errors to warnings, allowing [parsing](/page/Parsing) to continue while flagging issues for correction. Proper syntax adherence ensures robust handling across parsers and integrations.[](https://jsdoc.app/tags-type)
## Core Tags and Annotations
### Parameter and Return Tags
The `@param` [tag](/page/Tag) is used to document the [parameter](/page/Parameter)s of a [function](/page/Function), specifying the name, type, and description for each input argument. Its basic syntax is `@param {type} parameterName - description`, where the type is enclosed in curly braces and is optional, the parameter name is required, and the description follows a [hyphen](/page/Hyphen) for readability.[](https://jsdoc.app/tags-param) This [tag](/page/Tag) supports aliases such as `@arg` and `@argument`, which [function](/page/Function) identically to `@param`.[](https://jsdoc.app/tags-param)
For optional parameters, the name can be enclosed in square brackets, as in `@param {string} [optionalName] - An optional string value`, indicating the argument can be omitted. Default values are documented by including them within the brackets, for example, `@param {number} [count=1] - Number of items, defaults to 1`. Variadic parameters, representing rest arguments, are denoted with ellipsis notation like `@param {...string} items - Variable number of string items`. Union types for parameters that accept multiple possible types are expressed using the pipe operator, such as `@param {string|number} value - A value that can be a string or number`; these type expressions follow the syntax detailed in the type documentation.[](https://jsdoc.app/tags-param)
The `@returns` tag documents the value returned by a function, with the syntax `@returns {type} description`, where the type is optional and the description provides context about the output. It accepts aliases like `@return`, which behaves the same way. For functions that return nothing, the type can be omitted or specified as `{void}`; asynchronous functions commonly use `@returns {Promise<type>}` to indicate a promised result, such as `@returns {Promise<string>} A resolved string value`. Union types are also supported here, e.g., `@returns {number|string} Either a number or string`.[](https://jsdoc.app/tags-returns)
These tags are particularly valuable for documenting overloaded functions, where multiple sets of `@param` and `@returns` tags describe each possible signature, enabling clear [API](/page/API) documentation for polymorphic behaviors. In asynchronous contexts, combining `@returns` with [Promise](/page/Promise) types ensures generated documentation reflects modern [JavaScript](/page/JavaScript) patterns like async/await.[](https://jsdoc.app/tags-param)[](https://jsdoc.app/tags-returns)
### Type and Property Tags
The [@type](/page/type) tag in JSDoc allows developers to specify the [data type](/page/Data_type) of a [variable](/page/Variable), [property](/page/Property), or return value, enhancing [code](/page/Code) readability and enabling tools like type checkers to infer types accurately.[](https://jsdoc.app/tags-type) This tag supports a wide range of type expressions, including primitives like `{string}` or `{number}`, as well as more complex constructs such as unions `{number|string}`, making it essential for documenting dynamic [JavaScript](/page/JavaScript) code in a type-safe manner.[](https://jsdoc.app/tags-type)
For object literals and interfaces, the @property tag (or its synonym @prop) documents individual members of an object, specifying their types and descriptions within the context of a [class](/page/Class), [namespace](/page/Namespace), or [typedef](/page/Typedef).[](https://jsdoc.app/tags-property) The syntax follows `@property {type} name - description`, where the type can reference primitives or custom definitions, and optional properties are denoted with square brackets, such as `@property {string} [nickname] - Optional user nickname`.[](https://jsdoc.app/tags-property) This tag is particularly useful for listing static properties without defining actual code, ensuring comprehensive documentation for object structures.[](https://jsdoc.app/tags-property)
To create reusable custom type aliases, the @typedef tag defines named types that can be referenced elsewhere, promoting consistency across documentation.[](https://jsdoc.app/tags-typedef) Its syntax is `@typedef {type} name`, as in `/** @typedef {(number|string)} NumberLike */`, which can then be used in other tags like `@type {NumberLike} value`.[](https://jsdoc.app/tags-typedef) Complex types defined via @typedef often incorporate @property for detailing object members, such as `/** @typedef {Object} User @property {string} name @property {number} age */`, allowing for intricate data models without redundant declarations.[](https://jsdoc.app/tags-typedef)
JSDoc's type system supports advanced expressions for common scenarios, including nullable types with `?` (e.g., `{?string}` for string or null), arrays via `[type]` or `Array.<type>` (e.g., `{string[]}`), and function types like `{function(string, number): boolean}` to describe signatures precisely.[](https://jsdoc.app/tags-type) These constructs, rooted in Google Closure Compiler compatibility, enable detailed type annotations such as record types `{Object.<string, boolean>}` for key-value mappings.[](https://jsdoc.app/tags-type)
For integrating with third-party libraries, the @external tag marks symbols from external sources, allowing their types to be referenced without full redefinition, such as `@external [String](/page/String)` followed by extensions like `@method {function(): string} [rot13](/page/ROT13)`.[](https://jsdoc.app/tags-external) This facilitates documentation of interactions with libraries like [jQuery](/page/JQuery) or browser APIs, using prefixes like `external:XMLHttpRequest` in links or inheritance tags.[](https://jsdoc.app/tags-external) Such types can be employed in @param tags for [function](/page/Function) arguments, as detailed in the Parameter and Return Tags section.[](https://jsdoc.app/tags-type)
## Advanced Usage
### Module and Namespace Tags
In large [JavaScript](/page/JavaScript) projects, [module](/page/Module) and [namespace](/page/Namespace) tags in JSDoc enable developers to organize and [document](/page/Documentation) code structures that group related symbols, facilitating better navigation and understanding in generated [documentation](/page/Documentation). These tags are particularly essential for modular architectures, where code is divided into self-contained units that [export](/page/Export) specific members while hiding [implementation](/page/Implementation) details. By declaring [modules](/page/Module) and namespaces explicitly, JSDoc can generate hierarchical [documentation](/page/Documentation) that reflects the project's organization, often using namepaths prefixed with "module:" for cross-references.[](https://jsdoc.app/tags-module)
The [@module](/page/Module) tag declares the current [file](/page/File) as a module, treating all symbols within it as module members unless overridden. Its syntax is `@module [[{<type>}] <moduleName>]`, where the optional type expression (such as `{Object}`) specifies the module's type, and the name identifies the module for referencing; in JSDoc 3.3.0 and later, the name can include a "module:" prefix. For example:
/** @module myModule */
This creates namepaths like `module:myModule~foo` for inner members or `module:myModule.bar` for outer ones. If no name is provided, JSDoc derives it from the file path, such as "test" for "test.js". The tag supports linking via `{@link module:moduleName}` and is foundational for documenting exports in various module systems.[](https://jsdoc.app/tags-module)
The @namespace tag documents an object that groups related functions, classes, or properties into a logical [namespace](/page/Namespace), or defines a virtual namespace for symbols used elsewhere in the code. Its syntax is `@namespace [[{<type>}] <namespaceName>]`, requiring a name if a type is specified; the type, if provided, must align with the symbol, such as `{Object}` for object literals. For instance:
This creates namepaths like `module:myModule~foo` for inner members or `module:myModule.bar` for outer ones. If no name is provided, JSDoc derives it from the file path, such as "test" for "test.js". The tag supports linking via `{@link module:moduleName}` and is foundational for documenting exports in various module systems.[](https://jsdoc.app/tags-module)
The @namespace tag documents an object that groups related functions, classes, or properties into a logical [namespace](/page/Namespace), or defines a virtual namespace for symbols used elsewhere in the code. Its syntax is `@namespace [[{<type>}] <namespaceName>]`, requiring a name if a type is specified; the type, if provided, must align with the symbol, such as `{Object}` for object literals. For instance:
/** @namespace /
var MyNamespace = {
/* @function foo */
foo: function() {},
bar: 1
};
Or for a virtual namespace:
Or for a virtual namespace:
/** @namespace MyNamespace /
/* @function myFunction @memberof MyNamespace */
function myFunction() {}
Namespaces with unusual characters in names, like "!", require double quotes and backslash-escaped quotes if needed. This tag promotes [code organization](/page/Organization) by allowing members to be documented with `@memberof` for inclusion under the namespace.[](https://jsdoc.app/tags-namespace)
The @exports tag specifies the member exported by a module, crucial when the export differs from the default "exports" object or "module.exports" property, such as in custom assignments or AMD patterns. Its syntax is `@exports <moduleName>`, optionally prefixed with "module:" in JSDoc 3.3.0 and later. An example in an AMD module:
Namespaces with unusual characters in names, like "!", require double quotes and backslash-escaped quotes if needed. This tag promotes [code organization](/page/Organization) by allowing members to be documented with `@memberof` for inclusion under the namespace.[](https://jsdoc.app/tags-namespace)
The @exports tag specifies the member exported by a module, crucial when the export differs from the default "exports" object or "module.exports" property, such as in custom assignments or AMD patterns. Its syntax is `@exports <moduleName>`, optionally prefixed with "module:" in JSDoc 3.3.0 and later. An example in an AMD module:
/** @exports hello/world */
var ns = {};
return ns;
JSDoc automatically detects standard CommonJS exports without this tag, but @exports ensures accurate documentation for non-standard cases, generating correct namepaths like `module:hello/world.property`.[](https://jsdoc.app/tags-exports)
The @fileoverview tag, synonymous with @file and @overview, provides an overall [description](/page/Description) for the entire [file](/page/File), typically placed at the beginning of the source [code](/page/Code). Its syntax is `@fileoverview [description]`, allowing additional tags like @author. For example:
JSDoc automatically detects standard CommonJS exports without this tag, but @exports ensures accurate documentation for non-standard cases, generating correct namepaths like `module:hello/world.property`.[](https://jsdoc.app/tags-exports)
The @fileoverview tag, synonymous with @file and @overview, provides an overall [description](/page/Description) for the entire [file](/page/File), typically placed at the beginning of the source [code](/page/Code). Its syntax is `@fileoverview [description]`, allowing additional tags like @author. For example:
/**
- @fileoverview Manages the configuration settings for the widget.
- @author Rowina Sanela [email protected]
*/
This tag generates file-level summaries in [documentation](/page/Documentation), aiding in quick overviews of a module's purpose without delving into individual symbols.[](https://jsdoc.app/tags-file)
JSDoc handles different module patterns through these tags, adapting to CommonJS, ES modules, and UMD. For [CommonJS](/page/CommonJS) modules, @module identifies the file (e.g., `@module my/shirt` for `require('my/shirt')`), and @exports or @alias documents custom exports like local variables assigned to module.exports; JSDoc auto-detects properties on exports, module.exports, or this. In ES 2015 modules (supported since JSDoc 3.4.0), @module declares the module (e.g., `@module my/shirt` for `import * as myShirt from 'my/shirt'`), with exports documented directly on export statements—such as functions or constants—and namepaths like `module:my/shirt.Member`; imports can reference via `@see module:otherModule`. UMD patterns, which wrap code for multiple environments (e.g., browser globals, CommonJS, [AMD](/page/AMD)), are documented similarly by treating the wrapped export as a [global](/page/Global) or module via @exports on the return value, though this may require additional @global or verbose @memberof for full hierarchy; official support focuses on underlying patterns rather than UMD-specific syntax. Type expressions in these tags, like `{Object}` for namespaces, enhance precision by integrating with JSDoc's [type system](/page/Type_system).[](https://jsdoc.app/howto-commonjs-modules)[](https://jsdoc.app/howto-es2015-modules)[](https://jsdoc.app/tags-exports)
### Event and Callback Tags
JSDoc provides specialized tags to document asynchronous and [event-driven](/page/event-driven) patterns prevalent in [JavaScript](/page/JavaScript), such as custom events, emitted events, callbacks, and generator yields, enabling clearer documentation of concurrency behaviors in objects, classes, and functions. These tags facilitate the generation of structured [API](/page/API) references that describe how code handles events and asynchronous operations, which is essential for maintaining large-scale applications using event emitters or promises. By integrating these annotations, developers can specify event properties, callback signatures, and yielded values, improving code readability and tool integration without altering runtime logic.[](https://jsdoc.app/tags-event)[](https://jsdoc.app/tags-fires)[](https://jsdoc.app/tags-callback)
The [`@event`](/page/The_Event) tag documents custom events that can be emitted by objects or classes, typically represented as objects with specific [properties](/page/.properties). Its syntax is `@event <className>#[event:]<eventName>`, where the optional `event:` [namespace](/page/Namespace) is automatically prepended by JSDoc for linking purposes. For instance, in documenting a class method that handles a "[snowball](/page/Snowball)" event, one might specify [properties](/page/.properties) like `{[boolean](/page/Boolean)} isPacked` to describe the [event](/page/Event) [payload](/page/Payload). This tag pairs with `@fires` to indicate emission points and `@listens` for handlers, allowing comprehensive event lifecycle documentation; unlike earlier versions, JSDoc 3 focuses on event [content](/page/Content) rather than handler functions.[](https://jsdoc.app/tags-event)
To indicate that a method emits a particular event, the `@fires` tag (synonymous with `@emits`) is used with the syntax `@fires <className>#[event:]<eventName>`. This tag signals potential event triggers during method execution, and the event's details should be elaborated using `@event`. An example in a `Milkshake` class might annotate the `drink` method as follows:
This tag generates file-level summaries in [documentation](/page/Documentation), aiding in quick overviews of a module's purpose without delving into individual symbols.[](https://jsdoc.app/tags-file)
JSDoc handles different module patterns through these tags, adapting to CommonJS, ES modules, and UMD. For [CommonJS](/page/CommonJS) modules, @module identifies the file (e.g., `@module my/shirt` for `require('my/shirt')`), and @exports or @alias documents custom exports like local variables assigned to module.exports; JSDoc auto-detects properties on exports, module.exports, or this. In ES 2015 modules (supported since JSDoc 3.4.0), @module declares the module (e.g., `@module my/shirt` for `import * as myShirt from 'my/shirt'`), with exports documented directly on export statements—such as functions or constants—and namepaths like `module:my/shirt.Member`; imports can reference via `@see module:otherModule`. UMD patterns, which wrap code for multiple environments (e.g., browser globals, CommonJS, [AMD](/page/AMD)), are documented similarly by treating the wrapped export as a [global](/page/Global) or module via @exports on the return value, though this may require additional @global or verbose @memberof for full hierarchy; official support focuses on underlying patterns rather than UMD-specific syntax. Type expressions in these tags, like `{Object}` for namespaces, enhance precision by integrating with JSDoc's [type system](/page/Type_system).[](https://jsdoc.app/howto-commonjs-modules)[](https://jsdoc.app/howto-es2015-modules)[](https://jsdoc.app/tags-exports)
### Event and Callback Tags
JSDoc provides specialized tags to document asynchronous and [event-driven](/page/event-driven) patterns prevalent in [JavaScript](/page/JavaScript), such as custom events, emitted events, callbacks, and generator yields, enabling clearer documentation of concurrency behaviors in objects, classes, and functions. These tags facilitate the generation of structured [API](/page/API) references that describe how code handles events and asynchronous operations, which is essential for maintaining large-scale applications using event emitters or promises. By integrating these annotations, developers can specify event properties, callback signatures, and yielded values, improving code readability and tool integration without altering runtime logic.[](https://jsdoc.app/tags-event)[](https://jsdoc.app/tags-fires)[](https://jsdoc.app/tags-callback)
The [`@event`](/page/The_Event) tag documents custom events that can be emitted by objects or classes, typically represented as objects with specific [properties](/page/.properties). Its syntax is `@event <className>#[event:]<eventName>`, where the optional `event:` [namespace](/page/Namespace) is automatically prepended by JSDoc for linking purposes. For instance, in documenting a class method that handles a "[snowball](/page/Snowball)" event, one might specify [properties](/page/.properties) like `{[boolean](/page/Boolean)} isPacked` to describe the [event](/page/Event) [payload](/page/Payload). This tag pairs with `@fires` to indicate emission points and `@listens` for handlers, allowing comprehensive event lifecycle documentation; unlike earlier versions, JSDoc 3 focuses on event [content](/page/Content) rather than handler functions.[](https://jsdoc.app/tags-event)
To indicate that a method emits a particular event, the `@fires` tag (synonymous with `@emits`) is used with the syntax `@fires <className>#[event:]<eventName>`. This tag signals potential event triggers during method execution, and the event's details should be elaborated using `@event`. An example in a `Milkshake` class might annotate the `drink` method as follows:
/**
- Drink the milkshake.
- @fires Milkshake#drain
*/
Milkshake.prototype.drink = function() {
// ...
};
This ensures generated documentation highlights event flows, aiding in tracing asynchronous interactions.[](https://jsdoc.app/tags-fires)
For symbols that respond to events, the `@listens` tag specifies the event with syntax `@listens <eventName>`, often in the context of modules or methods. It complements `@event` by documenting listeners, such as a monitoring function that reacts to a "snowball" event with a `velocity` property of type `number`. In modular code, this might appear as:
This ensures generated documentation highlights event flows, aiding in tracing asynchronous interactions.[](https://jsdoc.app/tags-fires)
For symbols that respond to events, the `@listens` tag specifies the event with syntax `@listens <eventName>`, often in the context of modules or methods. It complements `@event` by documenting listeners, such as a monitoring function that reacts to a "snowball" event with a `velocity` property of type `number`. In modular code, this might appear as:
/**
- @listens module:hurler~event:snowball
*/
module.exports.reportThrowage = function(event) {
// Handle event
};
This tag supports event-driven architectures by clarifying dependencies on emitted signals.[](https://jsdoc.app/tags-listens)
Callback functions, common in asynchronous [APIs](/page/Apis), are documented using the `@callback` tag with syntax `@callback <namepath>`, which defines the function's parameters and [return](/page/Return) [value](/page/Value) akin to `@method`. It acts as a reusable type alias, suitable for class-specific (e.g., `Requester~requestCallback`) or global definitions. Parameters can include types like `{number} responseCode` and `{[string](/page/String)} responseMessage`, enabling precise specification of expected callback interfaces. This tag is particularly useful when callbacks are passed as arguments, promoting consistent [documentation](/page/Documentation) across functions.[](https://jsdoc.app/tags-callback)
JSDoc supports Promise-based asynchronous code through the `@async` tag, which marks functions declared with `async` syntax, indicating they return a `Promise`. With syntax `@async`, it is generally auto-detected by JSDoc but required for virtual comments; for return types, it integrates with `@returns` to specify resolved values like `Promise<string>`. For generator functions, the `@yields` tag (synonymous with `@yield`) documents yielded values using syntax `@yields [{type}] [description]`, available since JSDoc 3.5.0. An example for a Fibonacci generator:
This tag supports event-driven architectures by clarifying dependencies on emitted signals.[](https://jsdoc.app/tags-listens)
Callback functions, common in asynchronous [APIs](/page/Apis), are documented using the `@callback` tag with syntax `@callback <namepath>`, which defines the function's parameters and [return](/page/Return) [value](/page/Value) akin to `@method`. It acts as a reusable type alias, suitable for class-specific (e.g., `Requester~requestCallback`) or global definitions. Parameters can include types like `{number} responseCode` and `{[string](/page/String)} responseMessage`, enabling precise specification of expected callback interfaces. This tag is particularly useful when callbacks are passed as arguments, promoting consistent [documentation](/page/Documentation) across functions.[](https://jsdoc.app/tags-callback)
JSDoc supports Promise-based asynchronous code through the `@async` tag, which marks functions declared with `async` syntax, indicating they return a `Promise`. With syntax `@async`, it is generally auto-detected by JSDoc but required for virtual comments; for return types, it integrates with `@returns` to specify resolved values like `Promise<string>`. For generator functions, the `@yields` tag (synonymous with `@yield`) documents yielded values using syntax `@yields [{type}] [description]`, available since JSDoc 3.5.0. An example for a Fibonacci generator:
/**
- @yields {number} The next number in the Fibonacci sequence.
/
function fibonacci() {
// ...
}
This provides targeted annotation for iterative asynchronous patterns without overlapping basic return documentation.[](https://jsdoc.app/tags-async)[](https://jsdoc.app/tags-yields)
## Examples and Applications
### Documenting Functions
Documenting functions in JSDoc involves adding a block comment immediately before the function declaration, using tags to specify parameters, return values, exceptions, and usage examples. This approach enables tools to generate structured documentation and provides type hints for editors supporting JSDoc, such as [Visual Studio Code](/page/Visual_Studio_Code) or WebStorm.[](https://jsdoc.app/about-getting-started) The core tags for functions build on [basic](/page/Basic) syntax, focusing on clarity for parameters and outputs to aid code maintainability.[](https://jsdoc.app/tags-param)
A simple synchronous [function](/page/Function) can be documented using the `@param` tag for inputs, `@returns` for the output, and `@example` for usage illustration. The `@param` tag specifies the [parameter](/page/Parameter) name, type (optional), and description, following the syntax `@param {type} name - description`. For instance, consider a [function](/page/Function) that concatenates two [string](/page/String)s:
```javascript
/**
* Concatenates two strings.
* @param {string} first - The first string.
* @param {string} second - The second string to append.
* @returns {string} The concatenated result.
* @example
* const result = concatenate('Hello, ', 'world!');
* // Returns 'Hello, world!'
*/
[function](/page/Function) concatenate(first, second) {
return first + second;
}
This provides targeted annotation for iterative asynchronous patterns without overlapping basic return documentation.[](https://jsdoc.app/tags-async)[](https://jsdoc.app/tags-yields)
## Examples and Applications
### Documenting Functions
Documenting functions in JSDoc involves adding a block comment immediately before the function declaration, using tags to specify parameters, return values, exceptions, and usage examples. This approach enables tools to generate structured documentation and provides type hints for editors supporting JSDoc, such as [Visual Studio Code](/page/Visual_Studio_Code) or WebStorm.[](https://jsdoc.app/about-getting-started) The core tags for functions build on [basic](/page/Basic) syntax, focusing on clarity for parameters and outputs to aid code maintainability.[](https://jsdoc.app/tags-param)
A simple synchronous [function](/page/Function) can be documented using the `@param` tag for inputs, `@returns` for the output, and `@example` for usage illustration. The `@param` tag specifies the [parameter](/page/Parameter) name, type (optional), and description, following the syntax `@param {type} name - description`. For instance, consider a [function](/page/Function) that concatenates two [string](/page/String)s:
```javascript
/**
* Concatenates two strings.
* @param {string} first - The first string.
* @param {string} second - The second string to append.
* @returns {string} The concatenated result.
* @example
* const result = concatenate('Hello, ', 'world!');
* // Returns 'Hello, world!'
*/
[function](/page/Function) concatenate(first, second) {
return first + second;
}
This example highlights how @returns {type} description documents the function's output, while @example displays the provided code snippet as highlighted text in generated documentation.[19][20] Multiple @example tags can be used if needed, and captions can be added via <caption> for context.[20]
Optional parameters are denoted in @param with square brackets around the name, such as @param {string} [optionalParam], or by specifying a default value like @param {string= 'default'} name. The @throws tag documents potential errors, using syntax @throws {type} description or simply @throws description for free-form text; multiple instances are permitted for different conditions. For example:
javascript
function divide(dividend, divisor = 1) {
if (divisor === 0) {
throw new Error('Division by zero');
}
return dividend / divisor;
}
function divide(dividend, divisor = 1) {
if (divisor === 0) {
throw new Error('Division by zero');
}
return dividend / divisor;
}
Here, the optional divisor uses a default, and @throws alerts developers to runtime exceptions.[21][22]
Functions supporting overloads—multiple signatures for the same name—are documented by providing separate blocks of @param and @returns tags within the comment, separated by blank lines to delineate signatures. This allows tools to infer variants based on argument types or counts:
javascript
function add(a, b) {
return typeof a === 'number' ? a + b : a + b;
}
function add(a, b) {
return typeof a === 'number' ? a + b : a + b;
}
This method ensures each overload is clearly described without a dedicated @overload tag, which is more common in TypeScript extensions.[23]
Inline examples within descriptions use the {@code} inline tag for code snippets, such as "Use {@code myFunc(arg)} to call the function," which renders as formatted code in output. Markdown formatting, like backticks for inline code, is also supported in descriptions for readability.[17]
Common pitfalls include mismatched types between JSDoc annotations and actual function signatures, which can trigger warnings in IDE inspections or type checkers, leading to unreliable autocomplete or error detection. For instance, declaring @param {number} x when the function accepts a string causes signature mismatches. Additionally, placing multiple documentation blocks before a function results in only the last one being parsed, ignoring prior comments like TODO notes; consolidate them into a single /** block. Section separators using **** in comments may be misinterpreted as documentation starters, so use plain /* */ instead.[24][25]
Documenting Classes and Modules
JSDoc supports the documentation of JavaScript classes through tags that describe constructors, methods, and properties, enabling clear API descriptions for object-oriented code. For ES2015 classes, JSDoc automatically recognizes class declarations and expressions, parsing them without requiring explicit tags like @class or @constructor, though these can be added for additional clarity.[26] Instance methods are documented using @method, and properties with @instance to specify they belong to class instances.[26]
Consider a basic class example representing a point in a plane:
javascript
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
getX() {
return this.x;
}
getY() {
return this.y;
}
}
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
getX() {
return this.x;
}
getY() {
return this.y;
}
}
This structure documents the class overview, constructor parameters, and instance methods, generating output that distinguishes between the class as a whole and its members.[26]
Static methods are indicated with the @static tag, marking them as accessible on the class itself without instantiation, while inheritance is documented using @extends to link a subclass to its parent.[27][28] For instance, extending the Point class to create a Dot subclass:
javascript
class Dot extends Point {
constructor(x, y, width) {
super(x, y);
this.width = width;
}
getWidth() {
return this.width;
}
}
Dot.fromString = function(str) {
const [x, y, width] = str.split(',').map(Number);
return new Dot(x, y, width);
};
class Dot extends Point {
constructor(x, y, width) {
super(x, y);
this.width = width;
}
getWidth() {
return this.width;
}
}
Dot.fromString = function(str) {
const [x, y, width] = str.split(',').map(Number);
return new Dot(x, y, width);
};
The @extends tag ensures the subclass documentation reflects inherited members, and @static applies to class-level functions like factory methods.[26][28][27]
Modules in Node.js environments are documented using the @module tag to define the module scope, with classes exported via module.exports or similar patterns. The @classdesc tag provides a dedicated description for the class, separate from the constructor's documentation, which is particularly useful in modular exports.[29][30] An example of a module exporting a class:
javascript
function ColorMixer() {
this.blend = function(color1, color2) {
// Implementation
return 'blended';
};
}
module.exports = ColorMixer;
function ColorMixer() {
this.blend = function(color1, color2) {
// Implementation
return 'blended';
};
}
module.exports = ColorMixer;
Here, @module sets the namespace for exported symbols, and @classdesc offers a high-level class summary.[29][30][13]
Private members in classes are marked with the @private tag, indicating they are intended for internal use only and are typically excluded from generated documentation unless explicitly included via command-line options. Access levels can be further specified with @access, supporting values like private, protected, public, or package to control visibility in object-oriented designs.[31][32] For example, within a class:
javascript
class Vault {
_secretKey = 'hidden';
getData() {
return this._secretKey;
}
}
class Vault {
_secretKey = 'hidden';
getData() {
return this._secretKey;
}
}
The @private tag hides _secretKey by default, while @access protected limits getData to subclasses or internal code.[31][32]
A real-world snippet from a Node.js module, such as a bookshelf utility, illustrates combined usage in CommonJS:
javascript
this.Book = function(title) {
this.title = title;
this.getTitle = function() {
return this.title;
};
};
module.exports = this;
this.Book = function(title) {
this.title = title;
this.getTitle = function() {
return this.title;
};
};
module.exports = this;
This exports a constructor function as a class, using @module for the file scope, @classdesc for overview, @instance and @private for the property, and @access for the method.[13][29][30][31][32]
Editor Support
JSDoc annotations enable robust editor support by allowing integrated development environments (IDEs) to parse comments and provide features like autocompletion, type hints, and error detection during coding. This integration transforms plain JavaScript into a more type-aware experience without requiring a full switch to TypeScript, enhancing developer productivity through real-time feedback.[5]
In Visual Studio Code (VS Code), JSDoc is natively supported through built-in parsing that powers IntelliSense, offering intelligent code completion, parameter information, and hover tooltips based on annotations like @param and @type. For instance, typing a function with JSDoc comments triggers suggestions for argument types and return values, reducing errors and speeding up development. This feature leverages the TypeScript language service under the hood to interpret JSDoc in JavaScript files.[5][33]
WebStorm and other JetBrains IDEs provide comprehensive JSDoc support, including type hints derived from @type annotations to display parameter details and inferred return types inline. These IDEs also generate JSDoc stubs automatically when typing /** above functions, and they validate comment structures for consistency, such as ensuring required tags are present. This setup is particularly useful for large codebases where type safety improves navigation and refactoring.[34]
For projects mixing JavaScript and TypeScript, JSDoc serves as a fallback mechanism, allowing TypeScript's compiler and tools to check .js files annotated with JSDoc comments via a jsconfig.json configuration. This enables type checking, autocompletion, and error highlighting in editors like VS Code for untyped JavaScript, bridging the gap between dynamic and static typing without renaming files. Supported constructs include interfaces, generics, and unions, making it viable for gradual adoption.[4][35]
JSDoc validation during development is further enhanced by ESLint integration, particularly through the @typescript-eslint plugin, which extends linting to parse and enforce JSDoc comments in JavaScript files for type-aware rules. When combined with eslint-plugin-jsdoc, it checks for complete tags, valid types compatible with TypeScript or Closure Compiler, and consistent formatting, flagging issues like missing @param descriptions or invalid @type expressions. This setup requires configuring ESLint to use the TypeScript parser for JS files, ensuring annotations contribute to overall code quality checks.[36][37]
AI-powered tools incorporate JSDoc-aware suggestions to streamline documentation. In editors like Cursor, the built-in docstring generator auto-produces JSDoc comments for JavaScript functions, inferring types from context and code patterns to maintain consistency. Similarly, GitHub Copilot in VS Code leverages JSDoc annotations to refine its code completions, suggesting annotated functions with accurate parameter hints and even generating missing JSDoc blocks based on function signatures, making it a complementary tool for annotated workflows.[38]
JSDoc provides a command-line interface (CLI) for generating documentation from annotated source code, primarily producing static HTML output by default. The core command is jsdoc, which processes JavaScript files specified as arguments or via a configuration file; for instance, jsdoc -c conf.json loads settings from a JSON or JavaScript configuration file to define input sources, output directories, and other options like -d for the destination path or -a to include private members.[39][9] This CLI supports extensibility through plugins and templates, enabling customized workflows in build pipelines.
Templates in JSDoc control the visual and structural presentation of the generated documentation. The default template, known as "default," renders a multi-page HTML site with navigation, search, and syntax-highlighted code examples, configurable via options such as default.includeDate for timestamps or default.outputSourceFiles for source listings.[40] Custom templates like Minami, a minimalist single-page design, or Docdash, a responsive theme inspired by Lodash documentation, can be installed via npm and specified in the configuration's templates property to override the default styling and layout.[41] These templates are often community-maintained and focus on readability for large APIs.
Integration with build tools streamlines documentation generation during development and deployment. In npm projects, JSDoc is commonly added to package.json scripts, such as "docs": "jsdoc -c jsdoc.json", allowing execution via npm run docs for automated builds.[1] For bundlers like Webpack, the jsdoc-webpack-plugin hooks into the compilation process, running JSDoc on bundled outputs post-build to generate docs without separate CLI invocations, configurable with options like source inclusion patterns.[42]
As an alternative for TypeScript-heavy projects, TypeDoc serves as a documentation generator that supports a subset of JSDoc annotations alongside native TypeScript types, producing similar HTML outputs but with enhanced type inference and module resolution tailored to .ts files. This makes TypeDoc suitable for mixed JavaScript/TypeScript codebases where full TypeScript adoption is partial.
JSDoc's output formats extend beyond HTML through plugins and integrations. The built-in Markdown plugin converts inline Markdown in comments to HTML during generation, while tools like swagger-jsdoc parse JSDoc tags to produce OpenAPI-compliant JSON specifications for API documentation, integrable with Swagger UI.[43][44] Additional plugins enable JSON exports of the parsed AST for programmatic use in custom tools.
Standards and Best Practices
Coding Conventions
Coding conventions for JSDoc emphasize consistency, readability, and completeness to ensure documentation remains maintainable across projects and teams. Major style guides, such as Google's JavaScript Style Guide, mandate JSDoc for public APIs, requiring documentation for all classes, methods, and functions to facilitate code validation and comprehension.[45] In contrast, the Airbnb JavaScript Style Guide prioritizes structured multiline comments using /** ... */ blocks, which serve as the foundation for JSDoc adoption without specifying mandatory tags.[46] These conventions promote using JSDoc to annotate public-facing code, focusing on essential tags like @param, @returns, and @type to describe parameters, returns, and types explicitly.[45]
Descriptions in JSDoc should be written in complete sentences, starting with a verb phrase for methods (e.g., "Calculates the sum of two numbers") to provide clear, actionable information.[47] JSDoc supports HTML markup for formatting, such as bold or italic text, and can be extended with a Markdown plugin to enable richer elements like lists and links within descriptions.[47][43] For cross-references, the {@link} inline tag allows linking to other symbols or URLs, with optional custom text (e.g., {@link module:utils.add|add [function](/page/Function)}), enhancing navigability without disrupting the flow.[48]
Type annotations in JSDoc prioritize native JavaScript types (e.g., {string}, {number}, {boolean}) for simplicity and interoperability, resorting to custom types via @typedef only when native ones are insufficient for complex structures.[45][8] This approach ensures consistency, as seen in Google's guidelines, which require braces around types and modifiers like ? for optional or nullable values (e.g., {?string}), avoiding overly verbose custom definitions unless necessary for domain-specific logic.[45]
To track evolution, the @since tag specifies the version or date when a symbol was introduced (e.g., @since 1.2.0), aiding users in understanding API stability. Conversely, the @deprecated tag marks outdated symbols, optionally including migration guidance (e.g., @deprecated Use newMethod instead), which is required in Google style for any phased-out public APIs.[49][45]
For team-wide consistency, projects can define conventions in a .jsdoc.[json](/page/JSON) configuration file, specifying options like enabled tags, templates, and Markdown support to enforce standards during generation.[9] This file, passed via the -c command-line option, allows customization without altering individual comments, promoting uniform adoption across collaborators.[9]
Common Challenges and Solutions
One common challenge in JSDoc usage arises from parsing errors when dealing with complex type expressions, such as intricate union types or regex patterns in tags like @type or @pattern, which can cause the parser to fail or produce incomplete documentation. To address this, developers can simplify type expressions by breaking them into smaller, more manageable components or use the @ignore tag to exclude problematic symbols entirely from the generated output, ensuring the rest of the documentation proceeds without interruption.[50]
Another frequent issue involves incompatibilities with JavaScript minifiers, where tools like Terser strip out JSDoc comments during the minification process, potentially removing valuable documentation from production bundles.[51] Solutions include configuring the minifier to preserve specific comments via its --comments option with a regular expression that matches JSDoc blocks (e.g., /^/**/), or integrating plugins like terser-webpack-plugin that support comment retention for license and documentation purposes.[51]
Maintaining consistent JSDoc documentation across large codebases often proves difficult due to varying developer adherence and the volume of files involved. Automation via pre-commit hooks, such as those implemented with the pre-commit framework combined with the eslint-plugin-jsdoc, can enforce JSDoc requirements by linting staged files before commits, flagging missing or invalid annotations to promote uniformity without manual oversight.[52]
As of 2025, a notable gap persists in fully supporting JSX and TSX documentation without integrating TypeScript, as JSDoc's native parser struggles with JSX syntax in comments, leading to incomplete type inference for React components.[53] Workarounds include using JSDoc's @type tag to explicitly annotate JSX elements as React.Element or similar, and configuring editors like VS Code with checkJs enabled to leverage partial type checking, though this falls short of TypeScript's comprehensive JSX handling.[4]
Performance bottlenecks during JSDoc generation, particularly in expansive projects, can result in lengthy build times due to full codebase parsing on each run.[54] Optimizations involve omitting the --private command-line flag (default behavior) to exclude private members, thereby reducing the number of parsed symbols, alongside external caching strategies like incremental documentation tools or template-based regeneration to avoid reprocessing unchanged files.