| name | plugin-config |
| description | Write and debug rspress-plugin-api-extractor configuration in an rspress.config.ts. Use when editing the ApiExtractorPlugin(...) options object — api: vs apis: single/multi shapes, versions:/multiVersion, i18n locales, the api.fromDir/apis.fromDir helpers, baseRoute/apiFolder routing, categories/DEFAULT_CATEGORIES, externalPackages/autoDetectDependencies, source links, theme (Shiki) and --api-* CSS variables, llmsPlugin, observability/logLevel, the serve() dev/preview runner, .api.json model plumbing — or when a build fails with a route collision or a Twoslash/model error. Do NOT use for RSPress mechanics outside the plugin — _meta.json/_nav.json routing, page frontmatter, built-in components, --rp-* theming (see rspress-core); for what goes inside a with-api code fence — notation, @errors, ---cut--- (see twoslash); or for the editorial call of what deserves documenting (see doc-writer). |
plugin-config
Load this skill when you are configuring the rspress-plugin-api-extractor npm package — editing the ApiExtractorPlugin(...) options object inside a consumer's rspress.config.ts, wiring the model into the build, or reading a build error the plugin raised.
It owns the plugin's own surface: the config options, the fromDir helpers, the --api-* theme variables, the .api.json model plumbing, and the failure modes the plugin produces. Nothing in this skill is generic RSPress — that lives one skill over.
Route these adjacent decisions elsewhere:
- Generic RSPress mechanics —
_meta.json/_nav.json sidebar and nav, page frontmatter, built-in components, --rp-* theme variables — see rspress-core.
- What belongs inside a
with-api code fence — notation, @errors, ---cut---, the fence contract — see twoslash.
- The editorial call of what to document and when a snippet earns
with-api — see doc-writer.
Boundary: looks similar, is not
This skill and rspress-core both configure the same site, so their surfaces read as one thing. They are not.
- This skill owns everything that plumbs the API model into pages —
ApiExtractorPlugin options, .api.json models, the generated tree — and the --api-* CSS variables that theme the generated components.
rspress-core owns the generic RSPress surface — routing/nav files, frontmatter, components — and the --rp-* CSS variables that theme the site chrome.
--api-* and --rp-* are two different variable families. Restyling a signature block is --api-* (this skill); restyling the sidebar is --rp-* (rspress-core).
What the plugin does
ApiExtractorPlugin reads a Microsoft API Extractor model — a .api.json file describing a package's public API — and generates one MDX page per public API item (classes, interfaces, functions, type aliases, enums, variables, namespaces), plus the sidebar _meta.json files that structure them. It runs during the RSPress config() hook, so the pages exist before route scanning.
You give it, per documented API, up to three inputs: model (the .api.json, required), packageJson (for version and dependency detection, recommended), and tsconfig (to type-check the interactive code examples, optional). Everything else is presentation.
The five site shapes
Pick the shape first; the option follows from it. Each maps to a real example site under sites/.
| Site shape | Config | Example site |
|---|
| One package | api: { … } | sites/basic |
| Portal of several packages | apis: [ … ] | sites/multi |
| One package, many versions | api: { versions: { … } } + RSPress multiVersion | sites/versioned |
| One package, many locales | api: { … } + RSPress locales | sites/i18n |
| One package, many entry points | api: { … } (automatic — no extra config) | sites/effect |
api and apis are mutually exclusive: provide exactly one. versions lives only under api; apis entries always need an explicit model. i18n and multi-entry need no plugin-specific config at all — RSPress locales/exports drive them. Worked configs for all five are in references/recipes.md.
The fromDir shortcut
Rather than hand-write model/packageJson/tsconfig per package, point a helper at a built model folder (a directory holding a package.json, a *.api.json and optionally a tsconfig.json):
api: ApiExtractorPlugin.api.fromDir("./lib/models/my-library", { cwd: __dirname }),
apis: ApiExtractorPlugin.apis.fromDir("./lib/models", { cwd: __dirname }),
api.fromDir returns one config; apis.fromDir scans a parent directory and returns one per subfolder. Overrides you pass win over discovery. apis.fromDir is strict — every non-dotfile subdirectory must be a valid model folder or it throws. Discovery rules, baseRoute templates, and the return types (DirInfo, BaseRoute, FromDirOptions) are in references/config-reference.md.
Wiring the site
-
Routing. apiFolder (default "api") nests the generated pages under one folder segment; baseRoute prefixes the whole API. Under api: the default is /api; under apis: each entry defaults to /{packageName}/api so packages do not collide.
-
tsconfig. The package ships a base config sites extend: { "extends": ["rspress-plugin-api-extractor/tsconfig/rspress.json"] }. This is the site's own tsconfig.json, separate from the per-API tsconfig field that type-checks examples.
-
serve(). The plugin exports a serve runner for a two-line dev/preview script — it frees a stale port, spawns rspress dev|preview, and opens the browser once ready:
import { serve } from "rspress-plugin-api-extractor";
await serve({ mode: "dev", openPath: "/api/" });
It defaults to pnpm rspress dev on port 4173 and skips opening a browser when NO_OPEN is set.
The generated tree is plugin-owned
The plugin writes the entire tree under {baseRoute}/{apiFolder} — the MDX pages and their _meta.json files. Treat that folder as build output:
- Mount it, do not author inside it. Add one
dir entry for the API folder to your hand-written root _meta.json (array form — see rspress-core) so it appears in the sidebar. That is the only file you touch.
- Never hand-edit a generated page. The plugin rewrites changed pages and deletes stale/orphaned ones on every build, so edits inside the generated folder are silently reverted or removed. Fix the source: change the TSDoc and rebuild the model, or change the plugin config.
Common mistakes
- Setting both
api and apis. They are mutually exclusive; provide exactly one. A portal is apis: [], a single package is api: {}.
- Editing a generated page to fix a typo. It gets overwritten on the next build. The prose comes from the model's TSDoc — fix it in the documented package's source and rebuild the
.api.json.
- Expecting the generated pages in the sidebar without mounting them. The plugin writes the tree but does not touch your root
_meta.json; add the dir entry yourself.
- Reaching for
--rp-* to restyle a signature block. The generated components theme through --api-*; --rp-* is RSPress chrome. See references/theming.md.
- Using the
{packageName} baseRoute token for a scoped name. @scope/pkg interpolates verbatim, scope and slash included, landing in the URL. Prefer {dirname} or a callback.
- Expecting
llms*.txt files without RSPress llms: true. The integration post-processes RSPress's own LLMs output; with RSPress LLMs off there is nothing to process. See references/llms.md.
- Treating a Twoslash error in an example as a build failure. It renders inline and warns; the build still succeeds. The mechanics are
twoslash's; the config levers (externalPackages, errors: { example: "suppress" }) are in references/troubleshooting.md.
Reference map
Load on demand; none is required to write a first config. Each answers a narrower question than this file.
references/config-reference.md — every option, organized by where it lives: top-level, per-API, categories, source, theme, external types, OG images, observability, the fromDir helper surface.
references/recipes.md — the five site shapes as complete, working configs keyed to the example sites.
references/model-plumbing.md — the model-folder contract, getting the .api.json next to the docs, build ordering, and the forgotten-export / _base suppression setup.
references/theming.md — the --api-* variable groups, html.rp-dark overrides, the Shiki theme option and its dual-theme CSS mechanism, and the global popup CSS.
references/llms.md — the llms: true prerequisite, the per-package llms*.txt outputs, and the llmsUI placements.
references/troubleshooting.md — route collisions, Twoslash errors in examples, stale-cache resets, and the checkDeadLinks accommodation.