npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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-md

Usage

Print documentation for every exported symbol in a module:

pnpm exec exports-md src/index.ts

Query one or more exported symbols:

pnpm exec exports-md src/index.ts -- generateMarkdownForModule findNearestTypescript

Print documentation for multiple inputs:

pnpm exec exports-md src/index.ts src/feature.ts

Print symbol sections in reverse order:

pnpm exec exports-md src/index.ts -r

Render property TSDoc comments below declaration code blocks as a **Properties** list:

pnpm exec exports-md src/index.ts --propertyDocs list

Append a GitHub code search link to each symbol section:

pnpm exec exports-md src/index.ts --github.repository aleclarson/leylines --github.searchLinks

Write the Markdown to a file with normal shell redirection:

pnpm exec exports-md src/index.ts -- generateMarkdownForModule > src/index.md

Pipe the Markdown through another CLI command, such as Glow:

pnpm exec exports-md src/index.ts --pipe glow

When 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.json

Package directories are shorthand for their package.json:

pnpm exec exports-md .
pnpm exec exports-md packages/foo

Inspect published npm packages without adding them to the current project:

pnpm exec exports-md [email protected] @qubu/[email protected] @qubu/[email protected] --follow

Existing 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 -e

Write package entry point docs to an output directory:

pnpm exec exports-md package.json -o docs/api

Optional Agent Skill

Install the companion skill that teaches agents when and how to use exports-md:

npx skills add aleclarson/exports-md/skills

How 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.