- Getting Started with JSDoc
- JSDoc Block Tags
- @abstract (synonyms: @virtual)
- @access
- @alias
- @async
- @augments (synonyms: @extends)
- @author
- @borrows
- @class (synonyms: @constructor)
- @classdesc
- @constant (synonyms: @const)
- @constructs
- @copyright
- @default (synonyms: @defaultvalue)
- @deprecated
- @description (synonyms: @desc)
- @enum
- @event
- @example
- @exports
- @external (synonyms: @host)
- @file (synonyms: @fileoverview, @overview)
- @fires (synonyms: @emits)
- @function (synonyms: @func, @method)
- @generator
- @global
- @hideconstructor
- @ignore
- @implements
- @inheritdoc
- @inner
- @instance
- @interface
- @kind
- @lends
- @license
- @listens
- @member (synonyms: @var)
- @memberof
- @mixes
- @mixin
- @module
- @name
- @namespace
- @override
- @package
- @param (synonyms: @arg, @argument)
- @private
- @property (synonyms: @prop)
- @protected
- @public
- @readonly
- @requires
- @returns (synonyms: @return)
- @see
- @since
- @static
- @summary
- @this
- @throws (synonyms: @exception)
- @todo
- @tutorial
- @type
- @typedef
- @variation
- @version
- @yields (synonyms: @yield)
- Inline Tags
- JSDoc Examples
- Advanced but Common Usage by Developers
- Documenting Complex Types with @typedef
- Type-Safe Callbacks with @callback
- Documenting Promises and Async/Await
- Integrating JSDoc with Frameworks (React Example)
- Type Guards
- Annotating Destructured Parameters
- Annotating Function Signatures / Function as a Type
- Classes and Constructors
- Casting and Type Coercion in JSDoc
- Non-Null Assertion in JSDoc
- Generics in JSDoc
- Extending Interfaces
- Tuple Types
- Literal Types and Constants
- Importing External / Exported Types Directly in JSDoc
- Importing Non-TS Code and/or CommonJS Module.Exports
- Inline Code Examples
- VSCode - JavaScript Type Safety with JSDoc
- Sharing JSDoc Types Internally (Importing, Exporting, and Ambient Declarations)
- Generating Files From JSDoc
- Issues with Number Properties
- Additional Resources
JSDoc is a documentation generator for JavaScript that uses special comments to create API documentation. To use JSDoc, you add comments with specific tags (e.g., @param, @returns) to your code, and then run the JSDoc tool to generate HTML documentation.
Install JSDoc globally using npm:
npm install -g jsdocRun JSDoc on your JavaScript files:
jsdoc yourfile.jsThis generates HTML documentation in an ./out directory by default.
JSDoc can be configured using a JSON configuration file (e.g., jsdoc.json). Example:
{
"source": {
"include": ["src"],
"includePattern": ".+\\.js(doc)?$",
"excludePattern": "(^|\\/|\\\\)_"
},
"opts": {
"destination": "./docs",
"recurse": true
}
}Run with the configuration:
jsdoc -c jsdoc.jsonBelow is a comprehensive list of JSDoc block tags with examples for each.
Indicates a member must be implemented or overridden by a subclass.
/**
* @abstract
* @class
* @classdesc Represents a shape.
*/
class Shape {
/**
* Calculate the area of the shape.
* @abstract
* @returns {number} The area of the shape.
*/
calculateArea() {
throw new Error('Method must be implemented by subclass');
}
}Specifies the access level (private, package-private, public, or protected).
/**
* @class
* @access public
*/
class PublicClass {
/**
* @access private
*/
#privateMethod() {
// Private implementation
}
}Treats a member as if it had a different name.
/**
* @function
* @alias compute
*/
function calculate() {
return 42;
}Indicates a function is asynchronous.
/**
* Fetches user data.
* @async
* @returns {Promise<object>} User data.
*/
async function fetchUser() {
const response = await fetch('https://api.example.com/user');
return response.json();
}Indicates a class inherits from a parent class.
/**
* @class
* @augments Shape
*/
class Circle extends Shape {
// Circle implementation
}Identifies the author of an item.
/**
* @author John Doe <john.doe@example.com>
*/
function greet() {
return 'Hello, World!';
}Documents that an object uses something from another object.
/**
* @namespace
*/
const utils = {
/**
* @borrows Math.sqrt as sqrt
*/
sqrt: Math.sqrt
};Marks a function as a constructor to be called with new.
/**
* @class
* @classdesc A class representing a person.
*/
function Person(name) {
this.name = name;
}Describes the entire class.
/**
* @class
* @classdesc A utility class for string manipulation.
*/
class StringUtils {
// Methods
}Documents a constant.
/**
* The value of PI.
* @constant
* @type {number}
*/
const PI = 3.14159;Indicates a function is the constructor for a class.
/**
* @class
*/
const MyClass = (function() {
/**
* @constructs MyClass
*/
function MyClass() {
this.value = 0;
}
return MyClass;
})();Documents copyright information.
/**
* @copyright © 2025 Example Corp.
*/
function proprietaryFunction() {
// Proprietary code
}Documents the default value of a property.
/**
* @typedef {object} Config
* @property {string} [theme=dark] - The UI theme.
*/Marks an item as no longer preferred.
/**
* @deprecated Use newFunction instead.
*/
function oldFunction() {
// Old implementation
}Describes a symbol.
/**
* @description Adds two numbers.
* @param {number} a - First number.
* @param {number} b - Second number.
* @returns {number} Sum of a and b.
*/
function add(a, b) {
return a + b;
}Documents a collection of related properties.
/**
* @enum {string}
*/
const Colors = {
RED: 'red',
BLUE: 'blue',
GREEN: 'green'
};Documents an event.
/**
* @event MyClass#event:change
* @type {object}
* @property {string} newValue - The new value.
*/Provides an example of how to use an item.
/**
* Multiplies two numbers.
* @param {number} a - First number.
* @param {number} b - Second number.
* @returns {number} Product of a and b.
* @example
* const result = multiply(2, 3); // Returns 6
*/
function multiply(a, b) {
return a * b;
}Identifies the member exported by a module.
/**
* @module mathUtils
* @exports add
*/
function add(a, b) {
return a + b;
}Documents an external class, namespace, or module.
/**
* @external Array
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array}
*/Describes a file.
/**
* @file Utility functions for math operations.
*/Describes events a method may fire.
/**
* Triggers a change event.
* @fires MyClass#event:change
*/
function updateValue() {
// Event emission
}Describes a function or method.
/**
* @function
* @param {string} name - The name to greet.
* @returns {string} A greeting message.
*/
function greet(name) {
return `Hello, ${name}!`;
}Indicates a generator function.
/**
* Generates a sequence of numbers.
* @generator
* @yields {number} The next number in the sequence.
*/
function* numberGenerator() {
let i = 0;
while (true) yield i++;
}Documents a global object.
/**
* @global
* @type {object}
*/
var GLOBAL_CONFIG = { debug: true };Hides the constructor in documentation.
/**
* @class
* @hideconstructor
*/
class HiddenConstructor {
constructor() {
// Hidden
}
}Omits a symbol from documentation.
/**
* @ignore
*/
function internalFunction() {
// Not documented
}Indicates a symbol implements an interface.
/**
* @interface
*/
class Printable {
print() {}
}
/**
* @class
* @implements {Printable}
*/
class Document {
print() {
// Implementation
}
}Inherits documentation from a parent.
/**
* @class
*/
class Parent {
/**
* Parent method.
*/
method() {}
}
/**
* @class
* @augments Parent
*/
class Child extends Parent {
/**
* @inheritdoc
*/
method() {}
}Documents an inner object.
/**
* @namespace
*/
const App = {
/**
* @inner
* @type {object}
*/
Config: { debug: true }
};Documents an instance member.
/**
* @class
*/
class Counter {
/**
* @instance
* @type {number}
*/
count = 0;
}Documents an interface.
/**
* @interface
*/
class Logger {
/**
* Logs a message.
*/
log() {}
}Specifies the kind of symbol.
/**
* @kind class
*/
class MyClass {}Documents properties as if they belong to a named symbol.
/**
* @class
* @lends MyClass.prototype
*/
const props = {
/**
* A method.
*/
method() {}
};Identifies the license for the code.
/**
* @license MIT
*/
function openSourceFunction() {
// Code
}Lists events a symbol listens for.
/**
* @listens MyClass#event:change
*/
function handleChange() {
// Handle event
}Documents a member.
/**
* @class
*/
class Data {
/**
* @member
* @type {string}
*/
name = '';
}Indicates a symbol belongs to a parent symbol.
/**
* @namespace
*/
const Utils = {};
/**
* @memberof Utils
* @type {function}
*/
function utilFunction() {}Documents that an object mixes in members from another.
/**
* @mixin
*/
const Mixin = {
mixMethod() {}
};
/**
* @class
* @mixes Mixin
*/
class MyClass {}Documents a mixin object.
/**
* @mixin
*/
const LoggerMixin = {
log() {}
};Documents a JavaScript module.
/**
* @module myModule
*/Documents the name of an object.
/**
* @name MyFunction
* @function
*/
const fn = function() {};Documents a namespace.
/**
* @namespace
*/
const MyNamespace = {};Indicates a symbol overrides a parent.
/**
* @class
*/
class Base {
method() {}
}
/**
* @class
* @augments Base
*/
class Child extends Base {
/**
* @override
*/
method() {}
}Marks a symbol as package-private.
/**
* @package
*/
function packagePrivateFunction() {
// Package-private implementation
}Documents a function parameter.
/**
* Divides two numbers.
* @param {number} a - The dividend.
* @param {number} b - The divisor.
* @returns {number} The quotient.
*/
function divide(a, b) {
return a / b;
}Marks a symbol as private.
/**
* @private
*/
function privateFunction() {
// Private implementation
}Documents a property of an object.
/**
* @typedef {object} User
* @property {string} name - The user's name.
*/Marks a symbol as protected.
/**
* @protected
*/
class Base {
protectedMethod() {}
}Marks a symbol as public.
/**
* @public
*/
function publicFunction() {
// Public implementation
}Marks a symbol as read-only.
/**
* @class
*/
class Config {
/**
* @readonly
* @type {string}
*/
version = '1.0.0';
}Documents a required JavaScript module.
/**
* @requires module:lodash
*/
function useLodash() {
return _.clone({});
}Documents the return value of a function.
/**
* Calculates the square.
* @param {number} x - The number to square.
* @returns {number} The square of x.
*/
function square(x) {
return x * x;
}Refers to other documentation.
/**
* @see {@link https://example.com/docs}
*/
function externalDocs() {}Documents when a feature was added.
/**
* @since 2.0.0
*/
function newFeature() {}Documents a static member.
/**
* @class
*/
class MathUtils {
/**
* @static
* @returns {number}
*/
static random() {
return Math.random();
}
}Provides a shorter description.
/**
* @summary Performs a calculation.
* @description Performs a complex mathematical calculation.
* @returns {number}
*/
function complexCalculation() {}Documents what this refers to.
/**
* @this {Object}
* @returns {string}
*/
function getName() {
return this.name;
}Describes errors that could be thrown.
/**
* @throws {Error} If input is invalid.
*/
function validate(input) {
if (!input) throw new Error('Invalid input');
}Documents tasks to be completed.
/**
* @todo Add support for negative numbers.
*/
function abs(x) {
return Math.abs(x);
}Links to a tutorial file.
/**
* @tutorial getting-started
*/
function tutorialExample() {}Documents the type of an object.
/**
* @type {string}
*/
let message = 'Hello';Documents a custom type.
/**
* @typedef {object} Point
* @property {number} x - X coordinate.
* @property {number} y - Y coordinate.
*/Distinguishes objects with the same name.
/**
* @function
* @name log
* @variation 1
*/
function log(message) {}
/**
* @function
* @name log
* @variation 2
*/
function log(message, level) {}Documents the version number of an item.
/**
* @version 1.0.0
*/
function stableFunction() {}Documents the value yielded by a generator.
/**
* @generator
* @yields {string}
*/
function* stringGenerator() {
yield 'a';
yield 'b';
}Links to another item in the documentation.
/**
* See {@link MyClass} for details.
*/
function relatedFunction() {}Links to a tutorial (inline).
/**
* See {@tutorial getting-started} for more info.
*/
function inlineTutorial() {}/**
* @class
* @classdesc A class representing a vehicle.
*/
class Vehicle {
/**
* @param {string} model - The vehicle model.
*/
constructor(model) {
this.model = model;
}
/**
* Gets the model.
* @returns {string} The vehicle model.
*/
getModel() {
return this.model;
}
}/**
* @module myModule
*/
/**
* @function
* @param {number} x - A number.
* @returns {number} The doubled value.
*/
export function double(x) {
return x * 2;
}/**
* @module commonJsModule
*/
/**
* @function
* @param {string} text - Text to reverse.
* @returns {string} Reversed text.
*/
exports.reverse = function(text) {
return text.split('').reverse().join('');
};/**
* @module amdModule
*/
define([], function() {
/**
* @function
* @param {number} n - A number.
* @returns {number} The tripled value.
*/
return function triple(n) {
return n * 3;
};
});This section covers advanced but commonly used JSDoc patterns that developers encounter in real-world projects, particularly when working with complex JavaScript codebases, TypeScript-like type safety, or modern frameworks like React.
Developers often use @typedef to define complex data structures, such as nested objects or union types, to improve code clarity and IDE support.
/**
* @typedef {Object} Address
* @property {string} street - The street address.
* @property {string} city - The city name.
* @property {string} [zip] - Optional zip code.
*/
/**
* @typedef {Object} User
* @property {string} name - The user's name.
* @property {number} age - The user's age.
* @property {Address} address - The user's address.
*/
/**
* Creates a user profile.
* @param {User} user - The user object.
* @returns {string} A formatted user profile.
*/
function createProfile(user) {
return `${user.name}, ${user.age}, lives at ${user.address.street}, ${user.address.city}`;
}This example defines a User type with a nested Address type, enabling clear documentation and type checking in compatible IDEs.
The @callback tag is used to document callback function signatures, ensuring type safety for functions passed as arguments.
/**
* @callback ProcessCallback
* @param {string} data - The data to process.
* @param {number} index - The index of the data.
* @returns {string} The processed result.
*/
/**
* Processes an array of data with a callback.
* @param {string[]} data - The array to process.
* @param {ProcessCallback} callback - The callback function.
* @returns {string[]} Processed results.
*/
function processData(data, callback) {
return data.map((item, index) => callback(item, index));
}This ensures that developers know the expected parameters and return type of the callback function.
Promises and async/await are common in modern JavaScript, and JSDoc provides robust support for documenting them.
/**
* @typedef {Object} ApiResponse
* @property {number} status - HTTP status code.
* @property {Object} data - Response data.
*/
/**
* Fetches data from an API.
* @async
* @param {string} url - The API endpoint.
* @returns {Promise<ApiResponse>} The API response.
* @throws {Error} If the request fails.
*/
async function fetchData(url) {
const response = await fetch(url);
if (!response.ok) throw new Error('Request failed');
return {
status: response.status,
data: await response.json()
};
}This example shows how to document async functions with @async, @returns with Promise, and potential errors with @throws.
JSDoc is widely used in React projects to document components, props, and state. Below is an example of documenting a React functional component using JSDoc.
/**
* @typedef {Object} ButtonProps
* @property {string} label - The button's label.
* @property {boolean} [disabled=false] - Whether the button is disabled.
* @property {function(): void} onClick - Click handler.
*/
/**
* A customizable button component.
* @param {ButtonProps} props - The component props.
* @returns {JSX.Element} The rendered button.
*/
function Button({ label, disabled, onClick }) {
return (
<button disabled={disabled} onClick={onClick}>
{label}
</button>
);
}This example demonstrates how to document React props with @typedef and the component itself, improving IDE support and documentation clarity.
Type guards narrow types within conditional blocks using the syntax @return {value is YOUR_TYPE}.
// @ts-check
/**
* @typedef {{model: string}} Robot
*/
/**
* @typedef {{name: string}} Person
*/
/**
* @param {object} obj
* @return {obj is Person}
*/
function isPerson(obj) {
return 'name' in obj
}
/**
* Say hello!
* @param {Robot | Person} personOrRobot
*/
function greet(personOrRobot) {
if (isPerson(personOrRobot)) {
// Intellisense suggests `.name`, but not `.model`
console.log(`Hello ${personOrRobot.name}!`);
// Below will throw type error
console.log(personOrRobot.model);
} else {
// Intellisense suggests `.model`, but not `.name`
console.log(`GREETINGS ${personOrRobot.model}.`);
}
}Annotate types for destructured variables or function arguments.
/**
* @typedef {object} DestructuredUser
* @property {string} userName
* @property {number} age
*/
/** @type {DestructuredUser} */
const {userName, age} = getUser();
/**
* @param {object} obj
* @param {string} obj.userName
* @param {number} obj.age
*/
function logUser({userName, age}){
console.log(`User ${userName} is ${age} years old.`);
}
/**
* @param {object} obj
* @param {number} obj.total
* @param {string} obj.vendorName
*/
const printReceipt = ({total, vendorName}) => {
// total and vendorName will have correct types! :)
}Type functions with return types after arguments.
/**
* @typedef {function(string): string} StringProcessor
*/
/** @type {StringProcessor} */
const upperCaser = (input) => {
return input.toUpperCase();
}
/**
* @typedef {Object<string, StringProcessor>} StringProcessorsCollection
*/
/** @type {StringProcessorsCollection} */
const myStringMethods = {
lowerCase: function(input) {
return input.toLowerCase();
}
}Document ES2015 classes, but note complexities with external documentation or IIFEs.
- Documenting outside implementation is complex; use .ts files for advanced cases.
- Avoid documenting IIFEs due to bugs.
Example of basic class:
/**
* @class
* @classdesc Represents a person.
*/
class Person {
/**
* @constructs Person
* @param {string} name - The name.
*/
constructor(name) {
this.name = name;
}
/**
* Greets the person.
* @returns {string} Greeting.
*/
greet() {
return `Hello, ${this.name}!`;
}
}Use parenthesis for simple casting; advanced for non-overlapping types.
/** @type {unknown} */
let huh;
/** @type {number} */
const success = (huh);
/**
* @typedef {object} Person
* @property {string} name
* @property {number} age
*/
/** @type {number} */
let something;
/** @type {Person} */
const successAdvanced = /** @type {Person} */ (/** @type {unknown} */ (something));Workarounds for non-null assertions since post-fix ! is not supported.
/**
* Utility function since can't use post-fix assert in JSDoc
* @template T
* @param {T} thing
* @returns {Exclude<T, null>}
*/
function assertNonNull(thing) {
return /** @type {Exclude<T, null>} */ (thing);
}
const myElement = assertNonNull(document.querySelector('.my-class'));
myElement.setAttribute('data-greeting', 'hello!');Use @template T for generics.
/**
* Takes any object with a name prop and removes it
* @template T
* @param {T & {name?: string}} inputObj
* @returns {Omit<T, 'name'>}
*/
const deleteName = (inputObj) => {
/** @type {typeof inputObj} */
const copy = JSON.parse(JSON.stringify(inputObj));
delete copy.name;
return copy;
}
const nameLess = deleteName({
age: 50,
name: 'Gregory'
});Use intersection (&) or union (|) for extending.
/**
* @typedef {{title: string}} Media
*/
/**
* @typedef {Media & {author: string}} Book
*/Support for standard and literal tuples.
/** @typedef {[string, number]} NameAgeTuple */
/** @type {NameAgeTuple} */
const Robert = ['Robert Smith', 45];
/** @typedef {['Espresso', 'Drip']} CoffeeLiteralTuple */
/** @type {CoffeeLiteralTuple & string[]} */
const coffeeTypes = ['Espresso', 'Drip'];
coffeeTypes.push('Cold Brew'); // Type errorString literals and const assertions.
/** @typedef {'v1.0'} VersionString */
/** @typedef {'cat' | 'dog'} Pet */
/** @typedef {`${Pet}-${'collar' | 'food_bowl'}`} Accessory */
const AppInfo = /** @type {const} */ ({
appName: 'Widget Factory',
author: 'Joshua',
});Import types from modules.
/**
* @type {import('fs').Stats}
*/
let fsStats;
/** @typedef {import('unist').Node} AstNode */Use bracket notation for CommonJS.
/**
* @typedef {typeof import('../my-js-file')['myExportedFunc']} MyFunc
*/Use @example with fenced code blocks.
/**
* @typedef {'pinball' | 'skee-ball' | 'ddr' | 'whack-a-mole'} GameName
*/
/**
* Get an adjusted point total.
* @example
* ```js
* const adjusted = getAdjustedTotal({
* ddr: 2500,
* "whack-a-mole": 10
* }).adjustedTotal;
* ```
* @param {Partial<Record<GameName, number>>} gameHistory
* @returns {{total: number, adjustedTotal: number, avgWeight: number}} totals
*/
function getAdjustedTotal(gameHistory) {
// ...
}Enable with // @ts-check or settings. Simple example:
/**
* @type {google.maps.StreetViewPanorama}
*/
let pano = this.mapObjs.svPano;
/**
* @typedef {"Hello" | "World"} MyStringOptions
*/
/**
* @typedef {object} Person
* @property {string} name
* @property {number} age
* @property {boolean} likesCilantro
* @property {string} [nickname]
*/
/** @type {Person} */
let phil = {
name: 'Phil Mill',
age: 25,
likesCilantro: true
};
/**
* @param {Person} personObj
*/
function analyzePerson(personObj){
console.log(personObj.name);
}For globals, use ambient .d.ts files or globalThis.
Issues: Use tsconfig/jsconfig, check for mismatched TS versions.
Pass typedefs or inferred types; use TS files for types without transpilation.
/** @typedef {{username: string, isAdmin: boolean, age?: number}} User */
// In another file:
/** @type {import('./alpha.js').User} */
const joe = { username: 'Joseph', isAdmin: false, age: 85 };Emit declarations with tsconfig and tsc.
tsconfig example:
{
"compilerOptions": {
"allowJs": true,
"declaration": true,
"noEmit": false,
"emitDeclarationOnly": true,
"outDir": "./types"
}
}Caveats: All-or-nothing; avoid hand-editing generated files.
Workaround for number keys in typedefs.
/**
* @typedef {{0: string, 1: string, 2: string}} Levels
*/- JSDoc Plugins: Extend JSDoc functionality by creating plugins. See the JSDoc plugins documentation.
- Markdown Plugin: Enable Markdown support with the JSDoc Markdown plugin.
- Tutorials: Add tutorials to your documentation using the
@tutorialtag. - Package File: Include package details with the
@filetag and apackage.json. - README File: Include a README file in your documentation for project overview.
| Resource | Type | Link |
|---|---|---|
| Official JSDoc Docs | Official Docs | https://jsdoc.app/ |
| Official TypeScript Docs (JSDoc) | Official Docs | https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html |
| Devdocs JSDoc | Searchable Docs | https://devdocs.io/jsdoc/ |
| Devhints Cheatsheet | Cheatsheet | https://devhints.io/jsdoc |
| Theyosh Cheatsheet | Printable Cheatsheet | https://theyosh.nl/speeltuin/dash/dash.js-2.0.0/build/jsdoc/jsdoc_cheat-sheet.pdf |
| Types in JS Repo | GitHub Repo | https://github.com/voxpelli/types-in-js |