@apiuikit/cli
v0.7.0
Published
Generate a static API documentation site from a local OpenAPI or AsyncAPI spec, powered by APIUIKit.
Readme
@apiuikit/cli
Generate a static API documentation site from a local or remote OpenAPI or AsyncAPI spec — no React, no frontend project required. Powered by APIUIKit.
Built for projects that don't have a React/frontend toolchain in the loop: Java/Spring, Maven, Go, Python, CI/CD pipelines, and docs-only repos.
Install
npm install -g @apiuikit/cliOr run it without installing:
npx @apiuikit/cli generate ./openapi.yamlUsage
| Command | What it does |
|---|---|
| apiuikit generate <input> | Build a static docs site from a spec |
| apiuikit validate <input> | Check a spec for schema errors |
| apiuikit serve [dir] | Preview a generated site locally |
apiuikit generate <input> [options]<input> is a .yaml, .yml, or .json OpenAPI or AsyncAPI document — either a local path or a http:///https:// URL. The spec type is detected automatically from its top-level openapi/swagger or asyncapi field. generate and validate both accept <input> on these same terms.
Options
| Flag | Description | Default |
|---|---|---|
| -o, --output <dir> | Output directory for the generated site | apiuikit-docs |
| -c, --config <file> | JSON or YAML config file passed through to apiuikit — path or URL | — |
| --header <file> | HTML file injected at the top of the page, before the documentation — path or URL | — |
| --footer <file> | HTML file injected at the bottom of the page, after the documentation — path or URL | — |
| -f, --force | Overwrite the output directory if it already contains files | false |
| --single-file | Embed the script and stylesheet in the HTML file instead of a separate assets/ directory — one portable file, but much larger (~3–4 MB) | false |
| --out-file-name <name> | Custom filename for the generated HTML file (only valid with --single-file; must end in .html or .htm) | index.html |
Examples
apiuikit generate ./openapi.yaml
apiuikit generate ./asyncapi.json --output ./site
apiuikit generate https://example.com/openapi.yaml
apiuikit generate ./spec.yaml --config ./apiuikit.config.json
apiuikit generate ./spec.yaml --header ./header.html --footer ./footer.html
apiuikit generate ./spec.yaml --output ./docs --force
apiuikit generate ./spec.yaml --single-file
apiuikit generate ./spec.yaml --single-file --out-file-name docs.html<input> also accepts a http:///https:// URL — the spec is fetched directly, nothing is downloaded to disk first. This is useful when the spec is published by another repo, an API gateway, or a docs CDN rather than checked into your project. --config, --header, and --footer accept a URL on the same terms.
By default, generate writes index.html alongside a self-contained script and stylesheet under assets/. Either way the output is fully static — open it directly from disk (file://) or serve it from any static host (GitHub Pages, S3, nginx, etc.). No build step, no server, no network calls at runtime.
Single-file output
--single-file embeds the script and stylesheet directly inside the HTML file instead of writing them to assets/, so the whole site is one file — handy for emailing, attaching, or dropping anywhere without keeping a folder together. By default that file is still named index.html. The tradeoff is size: the script is inlined rather than linked, so the file grows to several megabytes and the script is no longer separately cacheable. Rendered output is otherwise identical to the default mode.
apiuikit generate ./openapi.yaml --single-filePass --out-file-name (only valid with --single-file) to write a different filename — useful when the portable file is meant to be shared or dropped into another project directly:
apiuikit generate ./openapi.yaml --single-file --out-file-name widgets-api-docs.html--force only overwrites the files this run writes, so renaming with --out-file-name leaves any previous index.html in place. Remove the old file yourself if you don't want both sitting side by side — otherwise serve will keep preferring index.html.
Config
--config points at a .json, .yaml, or .yml file — a local path or a URL — whose contents are passed straight through as the config prop on the underlying <apiuikit-openapi-renderer>/<apiuikit-asyncapi-renderer> element — the same ConfigInterface used by apiuikit's React and web-component APIs (theme colors, show/expand toggles for sidebar/servers/schemas/code samples/etc., topOffset, custom request/reply labels, and more).
{
"show": { "sidebar": true, "codeSamples": false },
"theme": {
"dark": { "background": "#1a1b26", "surface": "#24283b", "textPrimary": "#c0caf5" }
}
}apiuikit generate ./openapi.yaml --config ./apiuikit.config.json
apiuikit generate ./openapi.yaml --config https://example.com/apiuikit.config.jsonHeader & footer
--header/--footer point at .html files — a local path or a URL — whose contents are injected verbatim (unescaped) around the documentation element — the header just after <body>, the footer just before </body>. Use them for banners, nav links, custom branding, or a page footer.
<!-- header.html -->
<div class="my-header">
<style>.my-header { padding: 8px 16px; background: #1a1b26; color: #fff; }</style>
Beta docs — <a href="https://example.com">back to site</a>
</div>apiuikit generate ./openapi.yaml --header ./header.html --footer ./footer.html
apiuikit generate ./openapi.yaml --header https://example.com/header.html --footer https://example.com/footer.htmlAny CSS in these files — <style> blocks, inline style="...", or a <link rel="stylesheet"> to an asset you manage yourself — is applied normally, since the fragment becomes real page markup. The <apiuikit-openapi-renderer>/<apiuikit-asyncapi-renderer> element renders inside a Shadow DOM, so your header/footer styles can't leak into (or be overridden by) the documentation UI — but there's no isolation between the header and footer themselves, or from the page shell's own minimal CSS. Scope your selectors with a unique class or ID (as above) to avoid collisions.
See examples/branding/ for a ready-to-use header/footer html fragment.
For example:
apiuikit generate ./openapi.yaml --header examples/branding/header.html --footer examples/branding/footer.htmlValidating a spec
apiuikit validate <input> [options]Runs real schema validation against a local or remote OpenAPI or AsyncAPI document, powered by @scalar/openapi-parser and @asyncapi/parser — the same parsers apiuikit itself uses. It exits 1 and prints every error if the spec is invalid, and 0 if it's valid. AsyncAPI validation may also report warnings; these are printed but don't affect the exit code.
| Flag | Description | Default |
|---|---|---|
| -y, --yes | Install the required validator package automatically without prompting | false |
apiuikit validate ./openapi.yaml
apiuikit validate ./asyncapi.json
apiuikit validate https://example.com/openapi.yaml
apiuikit validate ./spec.yaml --yesInstalling the validators
The parsers are heavy, so they're never bundled with the CLI. They're declared as optional peer dependencies and only fetched the first time you actually run validate.
The cleanest option is to install the one you need up front, which skips the on-demand install entirely:
npm install --save-dev @scalar/openapi-parser@^0.28.10 # for OpenAPI specs
npm install --save-dev @asyncapi/parser@^3.6.0 # for AsyncAPI specsOtherwise validate handles it for you, and what happens depends on where you're running:
- In an interactive terminal, you're asked for confirmation, then the parser is installed as a dev dependency of the current directory — using whichever package manager the directory's lockfile points at (
pnpm-lock.yaml→ pnpm,yarn.lock→ yarn,bun.lockb→ bun, otherwise npm). This writes to that project'spackage.jsonandnode_modules, so if you're in a repo without a JavaScript toolchain, prefer installing the parser somewhere deliberate or use the pre-install commands above. - In CI or any non-interactive shell (no TTY, or
CIis set), there's no prompt:validatefails with manual install instructions unless you pass-y/--yes, which installs without asking.
Previewing the output
apiuikit serve [dir] [options]Serves a generated site over plain HTTP for local preview. [dir] defaults to apiuikit-docs, matching generate's default output, so apiuikit generate spec.yaml && apiuikit serve works with no extra flags. This is a convenience wrapper around Node's built-in http module — it adds zero new dependencies to the CLI, since the generated site needs no server at all (it opens fine straight from file://).
If the directory has no index.html, serve looks for a single .html/.htm file and uses that as the entry point at / — so a --single-file --out-file-name site still opens correctly. With zero or multiple candidates it warns and starts anyway; other files are still reachable, but visiting / returns 404.
| Flag | Description | Default |
|---|---|---|
| -p, --port <port> | Preferred port (auto-increments if taken) | 4300 |
| --open | Open the site in your default browser | false |
apiuikit serve
apiuikit serve ./site --port 5000
apiuikit serve --openHelp
apiuikit --help
apiuikit generate --help
apiuikit serve --help
apiuikit validate --helpHow it works
apiuikit generate reads your spec, detects whether it's OpenAPI or AsyncAPI, and embeds it directly into an index.html built around @apiuikit/web-component's <apiuikit-openapi-renderer> / <apiuikit-asyncapi-renderer> custom elements — the same rendering engine used by APIUIKit's React components, packaged as a framework-agnostic web component.
License
Apache-2.0
