Skip to main content

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.


Purpose
  1. Install and configure docsgen for a single TypeScript package.
  2. Add JSDoc comments that produce rich generated pages.
  3. Build and inspect the generated output.
  4. 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> {
// ...
}
}
Key JSDoc elements
  • First paragraph becomes the symbol's description on the generated page.
  • @param documents function and constructor parameters.
  • @returns documents the return type.
  • @example renders 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],
],
],
};
OptionWhat it does
idUnique identifier for this docsgen instance. Used by the importer to find the right output.
outDirWhere generated MDX files are written, relative to the Docusaurus site root.
titleDisplay name for the package in generated pages.
dirPath to the package root (where tsconfig.json lives).
entryPathTypeScript entry point(s) that TypeDoc will parse.
tsconfigDirDirectory 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;

Summary

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.