exports-md
v0.2.16
Published
Generate Markdown API docs from exported TypeScript declarations.
Readme
exports-md
When you encounter an unfamiliar TypeScript module, you may need to know what
you can import, which arguments it accepts, and what it returns. exports-md
collects exported signatures and existing documentation comments into Markdown
you can read, save, or share, including with a coding agent.
If your editor or the package's documentation already answers your question, you may not need this tool. It does not supply missing explanations or verify runtime behavior.
Try one complete example to see the source, command, and generated Markdown together. See when it is useful before deciding whether to add it to your workflow.
Install
You need Node.js ^22.18.0 or >=24.2.0, pnpm, and TypeScript installed in
your project or a parent workspace. Install the CLI in the project:
pnpm add -D exports-mdUsage
Print documentation for every exported symbol in a module:
pnpm exec exports-md src/index.tsQuery one or more exported symbols:
pnpm exec exports-md src/index.ts -- generateMarkdownForModule findNearestTypescriptPrint documentation for multiple inputs:
pnpm exec exports-md src/index.ts src/feature.tsPrint symbol sections in reverse order:
pnpm exec exports-md src/index.ts -rRender property TSDoc comments below declaration code blocks as a **Properties** list:
pnpm exec exports-md src/index.ts --propertyDocs listAppend a GitHub code search link to each symbol section:
pnpm exec exports-md src/index.ts --github.repository aleclarson/leylines --github.searchLinksWrite the Markdown to a file with normal shell redirection:
pnpm exec exports-md src/index.ts -- generateMarkdownForModule > src/index.mdPipe the Markdown through another CLI command, such as Glow:
pnpm exec exports-md src/index.ts --pipe glowWhen invoked by a person, command defaults can be customized in ~/.config/exports-md.json:
{
"follow": true,
"github": {
"repository": "aleclarson/exports-md",
"searchLinks": true
},
"propertyDocs": "list",
"pipe": "glow",
"sortByName": true
}The config accepts the long option names shown by exports-md --help; github.repository
and github.searchLinks are nested under github. Explicit command-line options override the
configured defaults. The config is ignored when @vercel/detect-agent identifies an agent caller,
keeping agent output deterministic.
Print documentation for every declaration entry point in a package export map:
pnpm exec exports-md package.jsonPackage directories are shorthand for their package.json:
pnpm exec exports-md .
pnpm exec exports-md packages/fooInspect published npm packages without adding them to the current project:
pnpm exec exports-md [email protected] @qubu/[email protected] @qubu/[email protected] --followExisting files and directories are treated as local inputs. If an input does
not exist locally and looks like a registry package spec, exports-md uses npm
to fetch its tarball into a temporary directory. It does not install the
package or its dependencies into the current project. npm must be available
on PATH.
Package inputs follow relative imports and re-exports to their declarations by default. For a module input, enable either behavior explicitly:
pnpm exec exports-md src/index.ts -f
pnpm exec exports-md src/index.ts -i
pnpm exec exports-md src/index.ts -eWrite package entry point docs to an output directory:
pnpm exec exports-md package.json -o docs/apiOptional Agent Skill
Install the companion skill that teaches agents when and how to use exports-md:
npx skills add aleclarson/exports-md/skillsHow it works
exports-md resolves the nearest node_modules/typescript from the current working directory, so declaration emit uses the TypeScript version installed by the target project. This TypeScript installation is also used to parse declarations from fetched packages.
The tool emits declarations in memory, parses the resulting .d.ts, and renders Markdown sections from exported declarations and their leading TSDoc comments. Property TSDoc comments stay inside declaration code blocks by default. With --propertyDocs list, property comments are removed from interface and object type code blocks and rendered below the block as a **Properties** list. When a symbol query is provided, the output includes requested exports plus local declaration dependencies needed to understand their signatures. With --groupBySyntax, same-module export sections are grouped under H2 headings by category: functions, classes, constants, remaining non-types, then types. Symbols inside those groups use H3 headings. With --sortByName, same-module export sections are printed alphabetically, with lowercase symbols first and all-caps symbols last. When both sort options are used, export category takes precedence over symbol name. With --reverseSymbols, rendered symbol sections are printed in reverse order after sorting while heading and reference import/re-export blocks stay in place.
With --github.searchLinks, every symbol section ends with a GitHub code search link. Set --github.repository to the owner/repo repository name used by those links.
When the input is package.json, the tool reads the exports field and renders each declaration entry point with a separate H1 based on the package name and export subpath, such as foo for . and foo/bar for ./bar. Export-map entries with types targets use those targets. A package's top-level types or typings field takes precedence over inferred JavaScript declaration targets when the root export has neither a types condition nor an explicit declaration or TypeScript source target. Wildcard targets are expanded against the package files and rendered with their concrete export subpaths. Entries without declaration targets use string .js, .mjs, or .cjs targets rewritten to .d.ts, .d.mts, or .d.cts, with a .d.ts fallback for packages that use that convention. Non-JavaScript/TypeScript entries such as ./package.json are skipped. With --outDir, each entry point is written as a .md file under the output directory, preserving the target files’ folder structure relative to their shared common root.
Module inputs include import and re-export reference lines by default. With --follow, relative imports and re-exports are followed to their declarations. For fetched npm packages, this follows only files inside the fetched package; dependencies are not installed or fetched recursively. Import-only symbols referenced by exported declaration signatures are omitted instead of rendered as standalone API sections; when those symbols come from declaration files, the JavaScript API returns warnings because the public signature is exposing an unreachable type. With --followReExports, or for package inputs by default, relative re-exports are followed to their declarations, including bundled patterns that import aliased names from a relative chunk and export those names through a local export list. Exported imported aliases are rendered with the rest of the normal symbols, so --groupBySyntax uses one set of syntax category headings per document. Non-relative package imports, non-relative package re-exports, and namespace imports/re-exports are still rendered as reference lines.
Rendered Markdown is cached in the system temp directory using the input path, source content, tsconfig content, requested symbols, heading, package version, and renderer version. Output that follows imports or re-exports is not cached, because it depends on additional declaration files.
