---
title: "AsyncAPI Generation"
description: "\"AsyncAPI Generation\" is a robust subsystem dedicated to transforming complex AsyncAPI specifications into structured, navigable documentation. By leveraging a modular architecture, it abstracts th..."
last_updated: "2026-07-02T09:46:39.0231+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/api-documentation/asyncapi-generation"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/asyncapi/src/types/asyncapi-3.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/types/asyncapi-3.ts)
- [packages/typescript/src/ui/auto-type-table.tsx](https://github.com/blade47/fumadocs/blob/main/packages/typescript/src/ui/auto-type-table.tsx)
- [packages/openapi/src/types/openapi.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/types/openapi.ts)
- [packages/asyncapi/src/server/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/server/index.tsx)
- [packages/openapi/src/server/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/server/index.tsx)
- [packages/asyncapi/src/generate-file.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/generate-file.ts)
- [packages/openapi/src/utils/pages/builder.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/utils/pages/builder.ts)
- [packages/api-docs/src/components/schema/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/api-docs/src/components/schema/index.tsx)
- [packages/mdx/src/runtime/server.ts](https://github.com/blade47/fumadocs/blob/main/packages/mdx/src/runtime/server.ts)
- [packages/asyncapi/src/ui/index.tsx](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/ui/index.tsx)
- [packages/asyncapi/src/utils/document/dereference.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/document/dereference.ts)
- [packages/asyncapi/src/utils/document/load.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/document/load.ts)
- [packages/openapi/src/utils/document/dereference.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/utils/document/dereference.ts)
- [packages/asyncapi/src/utils/schema.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/schema.ts)
- [packages/openapi/src/utils/document/load.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/utils/document/load.ts)
- [packages/openapi/src/utils/pages/to-static-data.ts](https://github.com/blade47/fumadocs/blob/main/packages/openapi/src/utils/pages/to-static-data.ts)
- [packages/asyncapi/src/utils/traits.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/traits.ts)
- [packages/content-collections/src/configuration.ts](https://github.com/blade47/fumadocs/blob/main/packages/content-collections/src/configuration.ts)
- [packages/asyncapi/src/utils/pages/to-static-data.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/pages/to-static-data.ts)
- [packages/asyncapi/src/utils/pages/builder.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/pages/builder.ts)
- [packages/asyncapi/src/ui/bindings/protocols/mqtt.tsx](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/ui/bindings/protocols/mqtt.tsx)
- [packages/asyncapi/src/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/index.ts)
- [packages/python/fumapy/mksource/document_module.py](https://github.com/blade47/fumadocs/blob/main/packages/python/fumapy/mksource/document_module.py)
- [packages/asyncapi/src/ui/bindings/protocols/solace.tsx](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/ui/bindings/protocols/solace.tsx)
- [packages/asyncapi/src/utils/get-example-messages.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/get-example-messages.ts)
- [packages/api-docs/src/schema/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/api-docs/src/schema/index.ts)
- [packages/asyncapi/src/ui/bindings/protocols/index.ts](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/ui/bindings/protocols/index.ts)
- [packages/doc-gen/src/remark-docgen.ts](https://github.com/blade47/fumadocs/blob/main/packages/doc-gen/src/remark-docgen.ts)
- [packages/asyncapi/src/ui/bindings/protocols/anypointmq.tsx](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/ui/bindings/protocols/anypointmq.tsx)
- [packages/asyncapi/package.json](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/package.json)
</details>

"AsyncAPI Generation" is a robust subsystem dedicated to transforming complex AsyncAPI specifications into structured, navigable documentation. By leveraging a modular architecture, it abstracts the complexity of specification parsing and data normalization, enabling developers to integrate event-driven API documentation into their workflows with minimal friction. The subsystem primarily solves the problem of "specification drift"—the gap between technical documentation and implementation—by providing both runtime generation tools and static export capabilities.

Architecturally, the subsystem is built on a "builder" pattern that processes AsyncAPI specifications into a normalized, internal format, which then flows into dedicated layout engines. These engines generate the virtual files required by the broader Fumadocs documentation pipeline. By separating concerns between document loading, schema dereferencing, and output building, it ensures that changes in the specification format are isolated, while UI components can rely on a consistent, unified model for rendering.

The system interacts extensively with lower-level document processing utilities, such as dereferencing tools that resolve `$ref` links and bundling utilities that normalize external schema references. By integrating directly into the `fumadocs-core` ecosystem, it functions as a loader plugin or a build-time generator, facilitating a seamless transition from raw AsyncAPI JSON/YAML files to interactive, high-fidelity documentation pages.

## Document Loading and Bundling

The subsystem begins by transforming raw input (URLs, local file paths, or objects) into a standardized `LoadedDocument`. This process is governed by `loadDocument` in `packages/asyncapi/src/utils/document/load.ts`. The central utility, `bundle`, is used to normalize the schema, ensuring that all components are accounted for, and a check is performed to confirm the document contains the required `asyncapi` version field.

The loading process is designed with caching as a first-class citizen. Within `packages/asyncapi/src/server/index.tsx`, the `createAsyncAPI` factory function initializes a `schemaMap` (a `Map<string, Promise<LoadedDocument>>`). When `getSchema` is called, the system first checks this cache unless `disableCache` is explicitly enabled. This design prevents redundant network requests or filesystem reads, which is critical in dynamic server environments where documentation might be rendered on every request.

> [!NOTE]
> When using `getSchema` for documents not explicitly listed in the `input` array of `AsyncAPIOptions`, the system issues a console warning and skips caching for the resulting `LoadedDocument` to prevent unintentional memory usage.

Sources: [packages/asyncapi/src/server/index.tsx:75-101](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/server/index.tsx#L75-L101), [packages/asyncapi/src/utils/document/load.ts:7-22](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/document/load.ts#L7-L22)

## Page Building and Data Normalization

The generation flow follows a structured pipeline: `Schema` → `fromSchema` (Builder) → `toStaticData` → `VirtualFile`. The `fromSchema` function in `packages/asyncapi/src/utils/pages/builder.ts` acts as the primary orchestration layer. It iterates over the AsyncAPI object, using a configuration-driven approach to map specification elements to `OutputEntry` structures. These entries define the hierarchical nature of the documentation, distinguishing between "pages" and "groups".

The data flow for generating a page entry is as follows:
1. `fromSchema` initializes the `PagesBuilder` context.
2. The `create()` callback within the builder is invoked for each detected operation or group.
3. `onEntries` in the server index recursively processes these entries.
4. For each individual page, `getPageProps` and `toStaticData` convert the raw schema into properties compatible with the UI layer (TOC, metadata, etc.).

```typescript
// Simplified representation of the entry building process
const list = fromSchema(id, schema.bundled, builderOptions);

function onEntry(entry: PageOutput | OperationOutput) {
  const props = getPageProps(entry);
  // Pushes to the virtual files collection
  files.push({
    type: 'page',
    path: `${baseDir}/${entry.path}`,
    data: { ... } // Compiled props and metadata
  });
}
```
Sources: [packages/asyncapi/src/server/index.tsx:110-156](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/server/index.tsx#L110-L156), [packages/asyncapi/src/utils/pages/builder.ts:57-87](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/pages/builder.ts#L57-L87)

## Dereferencing Mechanism

The dereferencing subsystem is an essential step in resolving the complex, interlinked structure of AsyncAPI files. The function `dereferenceBundledDocument` (in `packages/asyncapi/src/utils/document/dereference.ts`) performs a synchronous dereference of the bundled document, creating a normalized schema object that the UI components consume.

Crucially, it tracks original references via a `dereferenceMap`. By providing the `setOriginalRef` callback to `dereferenceSync` from `@fumadocs/api-docs/schema/dereference`, it creates a bidirectional mapping between the flat, dereferenced object and the path where it originally lived. This allows the UI to display the exact original location of any schema node using the `getRawRef` method.

| Component | Responsibility |
| :--- | :--- |
| `dereferenced` | The fully expanded AsyncAPI object tree. |
| `getRawRef` | A function to map an object back to its original JSON Pointer. |
| `bundled` | The raw, unresolved input document. |

Sources: [packages/asyncapi/src/utils/document/dereference.ts:6-34](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/utils/document/dereference.ts#L6-L34)

## Protocol Binding Logic

AsyncAPI defines protocol-specific bindings (e.g., Kafka, MQTT, Solace) via `BindingObject` structures. The subsystem handles these dynamically through a mapping in `packages/asyncapi/src/ui/bindings/protocols/index.ts`. Each protocol implements a `ProtocolBindingDefinition`, which dictates how the specific server, channel, operation, or message binding is rendered.

The `getProtocolBinding` function performs a lookup on the `protocolBindings` object. If an unsupported protocol is encountered, it falls back to `unknownBinding`. This provides a safeguard for the documentation renderer, ensuring that unknown protocols do not crash the UI but rather display a default representation.

```typescript
export function getProtocolBinding(protocol: string): ProtocolBindingDefinition {
  const v = protocolBindings[protocol as never];
  if (v) return v;

  return {
    ...unknownBinding,
    label: protocol,
  };
}
```
Sources: [packages/asyncapi/src/ui/bindings/protocols/index.ts:25-55](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/ui/bindings/protocols/index.ts#L25-L55)

## Static File Generation

Beyond the server-side runtime, the subsystem supports generating documentation at build-time through `generateFiles` in `packages/asyncapi/src/generate-file.ts`. This utility scans the input, converts all pages to text (Markdown/MDX format), and writes them to the specified output directory.

The process supports a watch mode using `chokidar`, which is particularly useful for local documentation development. When files change, the `scan` function recursively traverses the output entries, invoking `toText` for each node to generate its serializable form.

> [!CAUTION]
> The `beforeWrite` lifecycle hook allows for external modification of the `OutputFile[]` array. Since this happens globally before write-to-disk, any destructive changes here will persist in the generated static output.

Sources: [packages/asyncapi/src/generate-file.ts:56-81](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/generate-file.ts#L56-L81)

## Data Models

The following table summarizes key interface structures used across the subsystem to maintain consistency between the raw specification and the rendered documentation.

| Entity | Primary Key | Used By |
| :--- | :--- | :--- |
| `AsyncAPIObject` | `asyncapi` | Parser / Loader |
| `OperationObject` | `action` | UI Layout / Builder |
| `MessageObject` | `payload` | UI Schema Resolver |
| `OutputEntry` | `path` | Page Builder |
| `InternalAsyncAPIMeta` | `action` | Loader Plugin |

Sources: [packages/asyncapi/src/types/asyncapi-3.ts:10-192](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/types/asyncapi-3.ts#L10-L192), [packages/asyncapi/src/server/index.tsx:246-250](https://github.com/blade47/fumadocs/blob/main/packages/asyncapi/src/server/index.tsx#L246-L250)

## Related

- [API Schema Processing](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/api-documentation/api-schema-processing)
- [API UI](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/api-documentation/api-ui)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/llms.txt) for all pages in this wiki.
