Getting Started
On this page
Point apiuikit at an AsyncAPI or OpenAPI document and get a full interactive documentation UI covering servers, channels and endpoints, operations, messages, and schemas, with no manual mapping required.
Install#
npm install apiuikitThat is everything you need if you already have a parsed document object. If you want to hand the library a raw YAML or JSON string instead, also install the peer dependency for the spec you are rendering:
npm install @asyncapi/parser # for AsyncAPI documents
npm install @scalar/openapi-parser # for OpenAPI documentsAvro and Protobuf message payloads work in both cases, with nothing extra to install.
Render a document#
Import the component and the stylesheet, and pass it your document. The stylesheet import is required; without it the widget renders unstyled.
import { AsyncAPI } from "apiuikit";
import "apiuikit/style.css";
import doc from "./asyncapi.json";
export default function App() {
return <AsyncAPI asyncapi={doc} />;
}OpenAPI works the same way, through the OpenAPI component:
import { OpenAPI } from "apiuikit";
import "apiuikit/style.css";
import doc from "./openapi.json";
export default function App() {
return <OpenAPI openapi={doc} />;
}If what you have is a raw string rather than a parsed object (something a user pasted in, or a file read at runtime), use AsyncAPIRenderer or OpenAPIRenderer instead. They parse and validate for you, and are covered in With Parser.
Render one section#
You do not have to take the whole widget. Every section works standalone: pass it a document and drop it into a layout you already have.
import { AsyncAPIOperations } from "apiuikit";
import doc from "./asyncapi.json";
export default function OperationsPage() {
return <AsyncAPIOperations document={doc} layout="stacked" />;
}AsyncAPIServers, AsyncAPIOperations, AsyncAPIMessages, and AsyncAPIInfo all work this way (OpenAPI equivalents: OpenAPIServers, OpenAPIEndpoints, OpenAPIWebhooks, and OpenAPIInfo), as does Schemas, which is shared by both specs. Use layout="stacked" when a section is embedded on its own: it drops the reserved right-hand gutter that keeps sections aligned inside the full widget.
To place several sections in your own arrangement, wrap them in a provider so the document is resolved once and shared:
import { AsyncAPIProvider, AsyncAPIServers, AsyncAPIOperations, Schemas } from "apiuikit";
export default function CustomLayout() {
return (
<AsyncAPIProvider document={doc}>
<AsyncAPIServers />
<AsyncAPIOperations layout="stacked" />
<Schemas layout="stacked" />
</AsyncAPIProvider>
);
}Render one item#
To show a single endpoint, webhook, operation, message, or schema inline, use the singular component. It renders that item as a card and fills the width by default.
import { OpenAPIEndpoint, Schema } from "apiuikit";
<OpenAPIEndpoint document={petstore} operationId="createPet" />
<Schema document={petstore} name="Pet" />OpenAPIWebhook, AsyncAPIOperation, and AsyncAPIMessage work the same way. Pass document when one stands alone, or render several inside OpenAPIProvider or AsyncAPIProvider and pass document once to the provider.
See Composables for the full list and their props.
Configure it#
Every component takes a config object. A few of the options you are most likely to reach for first:
<AsyncAPI
asyncapi={doc}
config={{
theme: { colors: { primary: { 600: "#1f6feb" } } },
show: { sidebar: false, search: false },
expand: { schemas: true },
sidePanel: { containment: "component" },
topOffset: 64,
}}
/>theme: brand colour scales plus per-mode surface and text colours.show: switch individual sections and controls off, including the sidebar, search, code samples, and the Copy-for-LLM button.expand: whether schema trees and message examples start open.sidePanel.containment:"viewport"(default) lets an operation's side panel cover the browser window;"component"clips it to the widget's own root element, which is what you want when the widget is embedded in a page rather than being the page.topOffset/sidePanel.topOffset: pixels of host-page chrome (a sticky navbar) to keep above the widget's fixed controls and a component-contained side panel.
Every option is listed in Configuration.
Link to a specific endpoint#
Pass initialLocation to open on a given tab and item, and onLocationChange to write the current selection back to the URL. A typical hash looks like #endpoints/get%20/pets or #operations/receiveLightMeasurement.
<OpenAPI
openapi={doc}
initialLocation={{ tab: "endpoints", key: "get /pets" }}
onLocationChange={(location) => {
const hash = location?.key
? `#${location.tab}/${encodeURIComponent(location.key)}`
: location
? `#${location.tab}`
: "";
window.history.replaceState(null, "", hash || window.location.pathname);
}}
/>The Deep linking guide covers parsing the hash on load, the tab/key values for both specs, and how this behaves under Next.js.
Using it outside React#
For Vue, Angular, Svelte, or plain HTML, use the web component package. React and the parsers are bundled inside it, so consumers install nothing else.
npm install @apiuikit/web-componentimport "@apiuikit/web-component";
import "@apiuikit/web-component/style.css";
document.querySelector("#api-doc").spec = rawYamlOrJsonString;Web Components covers CDN usage, modular per-element imports, section elements, configuration, and framework integration.
Server-side rendering#
apiuikit is a client-side library: it bundles DOMPurify, which assigns to self at module scope, and self does not exist in Node. Importing apiuikit anywhere in a server render path will throw.
In Next.js, load it through a dynamic import with SSR disabled. Note that a "use client" directive alone is not enough, because the App Router still server-renders client components for the initial HTML.
"use client";
import dynamic from "next/dynamic";
const ApiDocs = dynamic(() => import("./ApiDocs"), {
ssr: false,
loading: () => <div className="h-[640px] animate-pulse rounded-xl border" />,
});
export default function Page() {
return <ApiDocs />;
}Give the loading fallback the same dimensions as the widget so the page does not shift when the client chunk arrives.
Where to go next#
- Composables: render one item, or arrange sections yourself.
- Without Parser and With Parser: both entry points in full, for AsyncAPI and OpenAPI alike.
- Deep linking: shareable URLs for a specific endpoint, schema, or message.
- Plugins: add your own UI to a rendered document, like a "Try it" tab.
- Extensions: the
x-*fields apiuikit renders, and how to switch them off. - AI Export: making your docs readable by agents and crawlers.