The json generator writes each source file as a JSON document: a tree of
its headings, each with its metadata, signature or type, Markdown and code
examples, in a format a published JSON schema describes. Use it when a program
needs your API as data, such as an editor integration, a linter or a site of
your own.
To load every document from one file, add the
JSON bundle (json-all).
Debug JSON
(json-simple) is a different format: a dump of the API entries behind every
output, for debugging the pipeline.
npx @doc-kit/cli generate -t json -i "doc/api/*.md" -o out
The documents keep the input's directory layout, from where the glob starts:
doc/api/fs.md becomes out/fs.json, and doc/api/guides/streams.md becomes
out/guides/streams.json.
It also reads the
global options
output, minify, and repository and ref, which sourceLink.url points
into. Without a repository, sourceLink.url is null.
{ "$schema": "https://doc-kit.nodejs.org/schemas/api-doc/1.0.1.json", "id": "fs", "path": "/fs", "type": "module", "module": "fs", "title": "File system", "introducedIn": "v0.10.0", "sourceLink": { "path": "lib/fs.js", "url": "https://github.com/nodejs/node/blob/HEAD/lib/fs.js" }, "stability": { "index": "2", "description": "Stable" }, "added": [], "deprecated": [], "removed": [], "napiVersion": [], "changes": [], "description": "The `node:fs` module enables interacting with the file system in a\nway modeled on standard POSIX functions.\n\n…", "summary": "The `node:fs` module enables interacting with the file system in a way modeled on standard POSIX functions.", "examples": [], "children": [] }
A document stands for a source file and its title heading. Besides the fields every entry has, it carries these, most from the file's page metadata:
| Field | Type | Holds |
|---|---|---|
$schema | string | The URL of the schema the document conforms to, from schemaURL. Its last path segment is the schema version. |
id | string | The file's path in the input tree, slugged: fs, guides-streams. |
path | string | The file's path in the input tree, without extension: /fs. |
type | string | The file's type= directive: module (the default), misc or global. |
module | string | null | The name= directive. Without one, the id of a module document, and null for the others. |
introducedIn | string | null | The introduced_in= directive. |
sourceLink | object | null | The source_link= directive: path, as authored, and url, the file on GitHub at ref (null without a repository). |
children | Node[] | The file's other headings, as nodes nested by depth, in document order. |
The document and every node carry:
| Field | Type | Holds |
|---|---|---|
title | string | The heading text as authored, inline Markdown included. |
stability | object | null | The stability index: index, as authored ("1.1"), and description, the Markdown after it. |
added, deprecated, removed | string[] | Versions, as authored. |
napiVersion | number[] | The Node-API versions the entry is available in. |
changes | object[] | The change history, one record per change: versions, prUrl, commit and description. |
description | string | The body as Markdown (MDX, from MDX sources): everything under the heading except its metadata, its stability index and the typed list a signature or type was taken from. Reference links are inlined, and links to .md files point to the .html pages, as on the website. |
summary | string | A one-paragraph summary: the llm_description when there is one, else the first paragraph on one line, with links reduced to their text. |
examples | object[] | The fenced code blocks of the body, as language, displayName and code. They stay in description too. |
Every field is always present: what a source doesn't declare is null, an
empty string or an empty array.
A node is a heading below the title. Its kind says what the heading
documents
(how headings are classified)
and decides which further fields the node has:
kind | Heading | Further fields |
|---|---|---|
section | Anything else: prose, DEP0005: …, --flag | none |
class | Class: `net.Server` | extends |
constructor | `new Agent([options])` | signature |
method | `fs.readFile(path[, options], callback)` | signature |
staticMethod | Static method: `Buffer.from(string)` | signature |
property | `buf.length` | type, default |
event | Event: `'close'` | parameters |
Every node also carries:
| Field | Type | Holds |
|---|---|---|
id | string | The heading's slug, unique within the document. It's the heading's anchor on the website. |
name | string | The bare identifier: readFile, Server, close. A section's heading text. A name= directive under the heading overrides it. |
scope | string | global for headings typed global and in global documents, module otherwise. |
overloadOf | string | null | On the second and later of consecutive sibling headings documenting the same callable, the id of the first. |
children | Node[] | The headings nested under this one. |
The further fields come from the heading and the typed list under it:
| Field | On | Holds |
|---|---|---|
signature | constructors, methods and static methods | parameters, every parameter the heading declares, in order, and returns, the Returns: item or null. A parameter the list doesn't describe has a null type. |
extends | classes | The type of the Extends: item, else the extends in the heading (Class: `Foo extends Bar`), else null. |
type | properties | The type of the Type: item. Its description goes first in the node's description. |
default | properties | The default of the Type: item. |
parameters | events | The arguments the listeners receive. |
A parameter has a name, without ..., a type, a description, and:
default: the value as authored, without its code span, ornull.optional:truewhen the parameter is bracketed in the heading or has a default.rest:truewhen it's declared as...args.properties: its nested items, such as the properties of an options object or the arguments of a callback, each a parameter too.
A type has text, the annotation as a TypeScript type on one line, with |
between union members, and links, the names in it that resolved to
documentation, with their offsets in text (see
Types that link themselves).
A type the source doesn't document is null, never guessed.
For example, this method:
## `fsPromises.readFile(path[, options])` - `path` {string|URL} The file to read. - `options` {Object} - `encoding` {string|null} **Default:** `null`. - Returns: {Promise} Fulfills with the contents of the file. Reads the entire contents of a file.
has Reads the entire contents of a file. as its description, and this
signature (each type's links shortened to []):
{ "parameters": [ { "name": "path", "type": { "text": "string | URL", "links": [] }, "description": "The file to read.", "default": null, "optional": false, "rest": false, "properties": [] }, { "name": "options", "type": { "text": "Object", "links": [] }, "description": "", "default": null, "optional": true, "rest": false, "properties": [ { "name": "encoding", "type": { "text": "string | null", "links": [] }, "description": "", "default": "null", "optional": true, "rest": false, "properties": [] } ] } ], "returns": { "type": { "text": "Promise", "links": [] }, "description": "Fulfills with the contents of the file." } }
Each links array lists its type's names with where they point and their
offsets, such as
{ "name": "URL", "href": "https://developer.mozilla.org/docs/Web/API/URL", "start": 9, "end": 12 }
for URL in string | URL.
Every document's $schema points to the version of the schema it conforms to,
such as https://doc-kit.nodejs.org/schemas/api-doc/1.0.1.json. The schema
also ships in @doc-kit/core as @doc-kit/core/generators/json/schema.json,
with TypeScript types generated from it:
import { readFile } from 'node:fs/promises'; import type { Document, Node, } from '@doc-kit/core/generators/json/generated/schema'; const fs: Document = JSON.parse(await readFile('out/fs.json', 'utf-8')); const listMethods = (nodes: Array<Node>): void => { for (const node of nodes) { if (node.kind === 'method') { console.log( node.name, node.signature.parameters.map(p => p.name) ); } listMethods(node.children); } }; listMethods(fs.children);
For doc-kit contributors: schema.json is the source of truth for the format.
When you change it, bump the version in its $id, in SCHEMA_VERSION in
constants.mjs, and in the $id of the JSON bundle's schema and its
reference to this one, all together. Then regenerate the types with
node scripts/generate-json-types.mjs. The tests fail while the versions
disagree or the committed types are stale.