---
url: /docs/5.x/guide/concepts/ast.md
description: >-
  How Kubb's universal Abstract Syntax Tree decouples input formats like OpenAPI
  from the generators that emit code, so one plugin works against any spec.
---

# AST

Kubb's universal Abstract Syntax Tree is the contract between the two halves of the pipeline. [Adapters](/docs/5.x/guide/concepts/adapters) produce the AST from a specification (OpenAPI, AsyncAPI, JSON Schema, and so on), and [plugins](/docs/5.x/guide/concepts/plugins) consume it to emit files. Because every plugin reads the same tree, one plugin works against any spec a custom adapter supplies.

## The tree shape

A single `InputNode` sits at the top, holding reusable schemas and operations. Operations point at parameters, an optional request body, and responses. Each of those connects back to schemas.

A `SchemaNode` is discriminated by its `type`, which falls into one of three groups.

Request bodies and responses hold one `ContentNode` per content type (for example `application/json`), and each content node carries its own body schema.

* Every child slot is a node, so a single traversal drives both `transform` and `collect` across the whole tree.
* Every node also carries a `kind` field as the discriminant, so `switch (node.kind)` narrows the type for you.

## Spec-agnostic by design

A plugin never looks at OpenAPI directly. It reads the tree the adapter produces, which is why the same plugin works for OpenAPI 2.0, 3.0, 3.1, and any custom adapter you write.

## How the AST connects the pipeline

The same tree flows through four stages, each documented on its own page:

* [Adapters](/docs/5.x/guide/concepts/adapters) build the AST from a spec.
* [Plugins](/docs/5.x/guide/concepts/plugins) read it and emit files.
* [Macros](/docs/5.x/guide/going-further/macros) rewrite nodes before printing.
* [Parsers](/docs/5.x/guide/concepts/parsers) turn the emitted nodes into source code.

> \[!NOTE]
> Import the `ast` namespace and its `factory` node builders from [`kubb/kit`](/docs/5.x/guide/concepts/kit), alongside `definePlugin` and `defineGenerator`. Everything on this page, including the guards, the macros, the printer, and the visitors, comes from that same namespace. See the [Kit API reference](/docs/5.x/reference/kit) for the full list.
