Documenting a Single Package
This guide walks you through generating API documentation for a single TypeScript package, from installation to embedding live API fragments in hand-written guides. By the end, you will have auto-generated API pages and a hand-written guide that pulls method tables and parameter lists directly from your source code.
- Install and configure docsgen for a single TypeScript package.
- Add JSDoc comments that produce rich generated pages.
- Build and inspect the generated output.
- Embed API fragments in hand-written MDX using
@import.
Prerequisites
- Node.js 18 or later
- A Docusaurus 3 project (or a new one via
npx create-docusaurus) - A TypeScript package with exported symbols
Step 1 - Install Dependencies
npm install @docsgen/core @docsgen/docusaurus
Both packages are needed: @docsgen/core provides the generation engine and the importer remark plugin,
while @docsgen/docusaurus integrates generation into the Docusaurus build lifecycle.
Step 2 - Add JSDoc Comments to Your Source
Before configuring the plugin, make sure your TypeScript source has JSDoc comments. docsgen extracts descriptions, parameter info, return types, and usage examples from these comments.
Here is a minimal example of a well-documented module:
/**
* Configuration options for creating an HTTP client.
*/
export interface ClientOptions {
/** Base URL for all requests. */
baseUrl: string;
/** Default timeout in milliseconds. */
timeout?: number;
/** Custom headers applied to every request. */
headers?: Record<string, string>;
}
/**
* Creates a new HTTP client instance configured with the given options.
*
* The client handles request lifecycle including retries, timeouts, and
* response parsing. Use it as the main entry point for all HTTP calls.
*
* @param options - Configuration for the client
* @returns A configured client instance ready to send requests
*
* @example
* ```typescript
* const client = createClient({
* baseUrl: "https://api.example.com",
* timeout: 5000,
* });
* ```
*/
export function createClient(options: ClientOptions): Client {
// ...
}
/**
* Manages HTTP request lifecycle including caching, queuing, and retry logic.
*
* @example
* ```typescript
* const client = new Client({ baseUrl: "https://api.example.com" });
* const response = await client.get("/users");
* ```
*/
export class Client {
/** Send a GET request to the given path. */
async get<T>(path: string): Promise<T> {
// ...
}
/** Send a POST request with a JSON body. */
async post<T>(path: string, body: unknown): Promise<T> {
// ...
}
}
- First paragraph becomes the symbol's description on the generated page.
@paramdocuments function and constructor parameters.@returnsdocuments the return type.@examplerenders in the "Usage" section with syntax highlighting.- Property comments (
/** ... */above interface members) appear in property tables.
Step 3 - Configure the Plugin
In your docusaurus.config.ts, add the docsgen plugin:
import plugin from "@docsgen/docusaurus";
const config = {
// ...your existing config
plugins: [
[
"@docsgen/docusaurus",
{
id: "api",
outDir: "docs/api",
packages: [
{
title: "my-library",
dir: "../packages/my-library",
entryPath: "src/index.ts",
tsconfigDir: "../packages/my-library",
},
],
} satisfies Parameters<typeof plugin>[1],
],
],
};
| Option | What it does |
|---|---|
id | Unique identifier for this docsgen instance. Used by the importer to find the right output. |
outDir | Where generated MDX files are written, relative to the Docusaurus site root. |
title | Display name for the package in generated pages. |
dir | Path to the package root (where tsconfig.json lives). |
entryPath | TypeScript entry point(s) that TypeDoc will parse. |
tsconfigDir | Directory containing the tsconfig.json to use for type resolution. |
Step 4 - Configure Sidebars
Add an autogenerated sidebar for the API section in sidebars.ts:
const sidebars = {
// Your existing docs sidebar
docs: [{ type: "autogenerated", dirName: "guides" }],
api: [{ type: "autogenerated", dirName: "api" }],
};
export default sidebars;
docsgen writes _category_.json files in each category folder, so Docusaurus automatically picks up sidebar
positions and labels.
Step 5 - Build and Inspect
Run the build:
npm run build
Or start the dev server for immediate results:
npm run start
After building, the output directory contains:
docs/api/
options.json
my-library/
docs.json
package-config.json
index.mdx
Classes/
_category_.json
Client.mdx
Functions/
_category_.json
createClient.mdx
Types/
_category_.json
ClientOptions.mdx
Each .mdx file contains the symbol's name, description, type definition, parameters, return types, and usage
examples, all extracted from your TypeScript source.
Step 6 - Embed API Fragments in Guides
The generated API pages are useful on their own, but the real power comes from embedding live API fragments in
your hand-written documentation. Add the importer remark plugin to your Docusaurus config:
import { importer } from "@docsgen/core";
const config = {
presets: [
[
"classic",
{
docs: {
remarkPlugins: [
importer({
packageRoute: "api",
apiDir: "docs/api",
}),
],
},
},
],
],
};
Now you can write a guide that mixes narrative with live API data:
## Creating a Client
Use `createClient` to set up an HTTP client with your API's base URL:
(@import my-library createClient type=parameters&display=table)
The client instance provides methods for each HTTP verb:
(@import my-library Client type=methods&display=table)
The @import directives are resolved at build time. When you rename a parameter, add a method, or change a
return type, these tables update automatically on the next build.
Complete Configuration
Here is the full docusaurus.config.ts with both the plugin and importer configured:
import { importer } from "@docsgen/core";
import plugin from "@docsgen/docusaurus";
import type { Config } from "@docusaurus/types";
import type * as Preset from "@docusaurus/preset-classic";
const config: Config = {
title: "My Library",
url: "https://my-library.dev",
baseUrl: "/",
presets: [
[
"classic",
{
docs: {
sidebarPath: "./sidebars.ts",
remarkPlugins: [
importer({
packageRoute: "api",
apiDir: "docs/api",
}),
],
},
} satisfies Preset.Options,
],
],
plugins: [
[
"@docsgen/docusaurus",
{
id: "api",
outDir: "docs/api",
packages: [
{
title: "my-library",
dir: "../packages/my-library",
entryPath: "src/index.ts",
tsconfigDir: "../packages/my-library",
},
],
} satisfies Parameters<typeof plugin>[1],
],
],
};
export default config;
You installed @docsgen/core and @docsgen/docusaurus, added JSDoc comments to your TypeScript source,
configured the plugin for a single package, and set up the importer to embed API fragments in hand-written
guides. Every generated page and every @import directive updates automatically when your code changes.
See Configuration for the full options reference and
Importer for all available @import types and display modes.
