Extension registry
The Kubb extension registry lists reviewed plugins, adapters, and parsers. Each entry pins one npm version or one GitHub release. kubb add, kubb update, kubb list, kubb.dev, and Kubb Studio read it.
The base URL is https://kubb.dev/registry. The registry is a set of plain static JSON documents:
- Served as
application/json, with CORS allowed, so any site or tool can read them. - Answered directly, never through a redirect.
- Cached for 10 minutes (
cache-control: public, max-age=600).
kubb-labs/registry builds the documents on every merge and once a day.
Registry ids
An id is <owner>/<slug>, such as kubb-labs/plugin-zod:
<owner>is the GitHub owner of the source repository, in lowercase.<slug>is the package name without its scope.@kubb/plugin-zodgivesplugin-zod.- Both parts match
[a-z0-9]+(?:-[a-z0-9]+)*: lowercase letters and digits joined by single hyphens.
The CLI accepts a bare <slug> and reads it as kubb-labs/<slug>. An entry owned by kubb-labs has type: "official". Every other entry is community.
GET <base>/index.json
Returns every extension in the registry:
type RegistryIndex = {
version: 1
generatedAt: string
extensions: Array<RegistryEntry>
}The CLI rejects an index whose version is not 1. It skips an entry that fails validation and keeps the rest.
GET <base>/<owner>/<slug>.json
Returns one extension and the docs its pinned version ships:
type RegistryDetail = RegistryEntry & {
overview: string | null
options?: string | null
guides?: Array<RegistryGuide>
}
type RegistryGuide = {
id: string
title: string
description: string
content: string
}The fields come from the package's docs/ folder:
overviewis the Markdown ofdocs/overview.md, or the overview the reviewer wrote.optionsis the Markdown ofdocs/options.md, ornullwhen the package ships none.guidesholds one entry perdocs/guides/<id>.md, in file name order.idis the file name without.md,titleis the first#heading,descriptionis the first paragraph after it, andcontentis the whole file.
Read a missing options as null and a missing guides as []. An unknown id answers 404, and kubb add reports "<id>" is not in the registry at <registry>.
RegistryEntry
@kubb/core exports the RegistryEntry, RegistryIndex, RegistryDetail, and RegistryGuide types.
id
kubb-labs/plugin-zod.kind
manifest.kind.type
official when the owner is kubb-labs, otherwise community.artifact
The install pin the registry approved. It has one of two kinds:
{ kind: 'npm', package, version }:kubb addandkubb updateinstall<package>@<version>.{ kind: 'github', package, version, owner, repo, tag, commit }: a release of a package at the repository root.kubb addandkubb updateinstallgithub:<owner>/<repo>#<commit>.packageis thenamein itspackage.json, andtagnamesversion.
repository
manifest
kubb-extension.json of the pinned version, with the reviewer's main category and listing overrides applied. An official version released before manifests ships none. The index leaves out that extension until a version that ships a manifest is pinned.stats
submittedAt
publishedAt
reviewedAt
Timestamps are UTC, to the second, such as 2026-10-12T20:00:00Z.
The CLI skips an entry unless id is a full <owner>/<slug>, artifact is an npm or GitHub pin with an exact semver version, and manifest is valid with the entry's kind. A detail document's id must equal the id the CLI asked for.
Records
The reviewed records live in kubb-labs/registry at extensions/<owner>/<slug>.json. The registry's build turns them into the documents above. Merging a record approves its pinned version.
{
"$schema": "https://kubb.dev/schemas/registry-record.json",
"id": "kubb-labs/plugin-zod",
"artifact": { "kind": "npm", "package": "@kubb/plugin-zod", "version": "5.4.4" },
"repository": { "url": "https://github.com/kubb-labs/plugins/tree/main/packages/plugin-zod" },
"submittedAt": "2026-10-12T20:11:53Z",
"submittedBy": "stijnvanhulle",
"publishedAt": "2026-10-12T20:11:53Z",
"reviewedAt": "2026-10-12T20:11:53Z",
"categories": ["validation"]
}| Field | Written by | Meaning |
|---|---|---|
id, artifact, repository, submittedAt, publishedAt, reviewedAt | Bot | As in RegistryEntry. id must equal the file path. |
submittedBy | Bot | The GitHub user who opened the submission. |
categories | Reviewer | Category slugs. The first is the main one and replaces the manifest's category. |
listing | Reviewer | Optional overrides for displayName, description, tags, and icon. |
The record JSON Schema is https://kubb.dev/schemas/registry-record.json. To add a record, follow Submit to the registry.
Categories
| Slug | Use for |
|---|---|
types | Generate TypeScript types and interfaces. |
validation | Validate data at runtime with schemas. |
client | Generate HTTP clients that call the API. |
framework | Generate hooks and composables for UI frameworks. |
mocks | Generate mock data and mock servers. |
testing | Generate tests and test helpers. |
documentation | Generate API documentation. |
ai | Expose the API to AI agents and tools. |
output | Shape the generated files, such as barrel files. |
openapi | Read OpenAPI and Swagger specs. |
typescript | Print generated code as TypeScript. |
docs | Print generated code as Markdown. |
Host your own registry
Serve the same two documents from any static host, then point the CLI at it with KUBB_REGISTRY. To build them from your own records, fork kubb-labs/registry, replace extensions/, and run pnpm build. The dist/ folder is the whole registry.
KUBB_REGISTRY=https://registry.example.com kubb add acme/plugin-graphqlWith that base URL, the CLI reads https://registry.example.com/index.json and https://registry.example.com/acme/plugin-graphql.json. KUBB_REGISTRY must start with http:// or https://, and trailing slashes are removed.
Your documents must follow the shapes on this page, and index.json must set version: 1. Answer 404 for an unknown id. Studio always reads the kubb.dev index, so a private registry changes what the CLI installs, not what Studio lists.