# Node.js API Documentation Tooling

The Node.js API documentation is generated by an in-house tooling that resides
in the [nodejs/doc-kit](https://github.com/nodejs/doc-kit)
repository.

It is accessible in this repository from the `tools/doc` directory, where it is installed as an npm package.

The build process (using `make doc` or `make doc-only`) uses this tooling to
parse the markdown files in [`doc/api/`][] and generate the following:

1. Human-readable HTML in `out/doc/api/*.html`
2. A JSON representation in `out/doc/api/*.json`

These artifacts are published to nodejs.org for multiple versions of
Node.js. As an example the latest version of the human-readable HTML
is published to [nodejs.org/en/doc](https://nodejs.org/en/docs/),
and the latest version of the json documentation is published to
[nodejs.org/api/all.json](https://nodejs.org/api/all.json)

The artifacts are built as part of release builds by running the [doc-upload](https://github.com/nodejs/node/blob/1a83ad6a693f851199608ae957ac5d4f76871485/Makefile#L1218-L1224)
Makefile target as part of the release-sources part of the
iojs+release job.
This target runs the `doc` target to build the docs and then uses
`scp` to copy them onto the staging/www server into a directory of the form
`/home/staging/nodejs/<type>/<full_version>/docs` where <type> is e.g.
release, nightly, etc. The promotion step (either automatic for
nightlies or manual for releases) then moves the docs to
`/home/dist/nodejs/docs/\<full\_version>` where they are served by node.org.

**The key things to know about the tooling include:**

1. It can be invoked via executing `tools/doc/node_modules/.bin/doc-kit` (ex/ `$ tools/doc/node_modules/.bin/doc-kit generate ...`)
2. Its usage is detailed in the [nodejs/doc-kit README](https://github.com/nodejs/doc-kit/blob/main/README.md).
3. The tooling can process multiple files at a time.
4. The tooling uses a set of dependencies as described in the dependencies
   section.
5. The tooling parses the input files and does several transformations to the
   AST (Abstract Syntax Tree).
6. The tooling generates a JSON output that contains the metadata and content of
   the Markdown file.
7. The tooling generates a HTML output that contains a human-readable and ready
   to-view version of the file.

This documentation serves the purpose of explaining the existing tooling
processes, to allow easier maintenance and evolution of the tooling. It is not
meant to be a guide on how to write documentation for Node.js.

## Vocabulary & Good to Know's

* AST means "Abstract Syntax Tree" and it is a data structure that represents
  the structure of a certain data format. In our case, the AST is a "graph"
  representation of the contents of the Markdown file.
* MDN means [Mozilla Developer Network](https://developer.mozilla.org/en-US/)
  and it is a website that contains documentation for web technologies. We use
  it as a reference for the structure of the documentation.
* The
  [Stability Index](https://nodejs.org/dist/latest/docs/api/documentation.html#stability-index)
  is used to describe the Stability of a given Node.js module. The Stability
  levels include:
  * Stability 0: Deprecated. (This module is Deprecated)
  * Stability 1: Experimental. (This module is Experimental)
  * Stability 2: Stable. (This module is Stable)
  * Stability 3: Legacy. (This module is Legacy)
* Within Remark YAML snippets `<!-- something -->` are considered HTML nodes,
  that's because YAML isn't valid Markdown content. (Doesn't abide by the
  Markdown spec)
* "New Tooling" references to the (written from-scratch) API build tooling
  introduced in `nodejs/nodejs.dev` that might replace the current one from
  `nodejs/node`

## Basic Tooling Usage

```bash
# cd tools/doc
npx doc-kit
```

**OR**

```bash
# nodejs/node root directory
make doc
```

## Writing Documentation

There should be a 1:1 relationship between module source files (`lib/<module>.js`) and their documentation files (`doc/api/<module>.md`).

The `introduced_in` and `added` YAML properties should be set to `REPLACEME` for new features.
They will be replaced with the proper version later when it comes to releasing them.

````markdown
# module

<!--introduced_in=v0.10.0-->

> Stability: 2 - Stable

A description and examples.

## `module.property`

<!-- YAML
added: v0.10.0
-->

- {type}

A description of the property.

## `module.someFunction(x, y, [z=100])`

<!-- YAML
added: v0.10.0
changes:
  - version: v15.0.0
    pr-url: https://github.com/nodejs/node/pull/12345
    description: A description of the change.
-->

- `x` {string} The description of the string.
- `y` {boolean} Should I stay or should I go?
- `z` {number} How many zebras to bring. **Default:** `100`.

A description of the function.

\```cjs
// An example using CJS syntax.
const { someFunction } = require('module');
someFunction('a', true, 10);
\```

\```mjs
// An example using MJS syntax.
import { someFunction } from 'module';
someFunction('a', true, 10);
\```

## Event: `blerg`

<!-- YAML
added: REPLACEME
-->

- `anArg` {type} A description of the listener argument.

Modules don't usually raise events on themselves. `cluster` is the
only exception.

## Class: `SomeClass`

A description of the class.

### `SomeClass.classMethod(anArg)`

<!-- YAML
added: v0.10.0
-->

- `anArg` {Object} Just an argument.
  - `field` {string} `anArg` can have this field.
  - `field2` {boolean} Another field. **Default:** `false`.
- Returns: {boolean} `true` if it worked.

A description of the method for humans.

### `SomeClass.nextSibling()`

<!-- YAML
added: v0.10.0
-->

- Returns: {SomeClass | null} The next `SomeClass` in line.

`SomeClass` must be registered in `https://github.com/nodejs/doc-kit/blob/main/src/constants.mjs` to be properly parsed in `{type}` fields.

### `SomeClass.someProperty`

<!-- YAML
added: v0.10.0
-->

- {string}

The indication of what `someProperty` is.

### Event: `grelb`

<!-- YAML
added: v0.10.0
-->

- `isBlerg` {boolean}

This event is emitted on instances of `SomeClass`, not on the module itself.
````

[`doc/api/`]: https://github.com/nodejs/node/tree/main/doc/api
