CLI tool
cloudflare/chanfana avatar
cloudflare/chanfana

chanfana: OpenAPI schemas and validation for Hono and itty-router

OpenAPI 3 and 3.1 schema generator and validator for Hono, itty-router and more!

771 stars72 forksTypeScriptMIT

At a glance

What is it?
chanfana is Cloudflare's library that generates an OpenAPI 3 or 3.1 schema from class-based endpoints and validates incoming requests against it, working with Hono, itty-router and other routers. It is Zod v4 based, ships a CLI for schema extraction, and is used in the Radar public API.
Who is it for?
chanfana suits a team on Cloudflare Workers or any Hono or itty-router application that needs a real OpenAPI document and request validation without writing a spec by hand, since the schema comes from the same Zod definitions the runtime enforces. It does not suit an Express or Fastify codebase, since the router adapters are the integration point.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What chanfana does and what it replaced

chanfana is an OpenAPI 3 and 3.1 schema generator and validator for Hono, itty-router and more. It was previously known as itty-router-openapi, which tells you where the project came from, and the README frames it as a library that adds schema generation and validation to any router, meant to be a powerful and lightweight library for Cloudflare Workers but running on any runtime the base router supports.

The feature list is short and specific. OpenAPI 3 and 3.1 schema generation and validation. Zod v4 compatibility with full TypeScript inference. Everything written in TypeScript. Class-based endpoints. Query, path, header and body TypeScript inference. The ability to extend an existing Hono or itty-router application without touching old routes. And a CLI to extract the schema.json from your code.

The last of those is the one that changes a team's workflow. The schema is not a separate artifact to maintain. It is derived from the code that handles the request, so a validation rule and the OpenAPI description of that rule come from the same Zod object. That removes the class of bug where the documentation and the implementation drift apart.

The project also states that it is considered stable and production ready, and that it is used with the Radar 2.0 public API and many other Cloudflare products. That is a strong signal for a library in this niche, and it is the reason to look at the design rather than just the feature list.

Installing the package and the AI assistant skills

The package installs from npm.

bash
npm i chanfana --save

The package metadata requires Node 18 or above, and the distribution carries both ESM and CommonJS builds with separate type definitions, so a project on either module system can consume it. The bin entry points at dist/cli.js, and the author is listed as Gabriel Massadas, who wrote it at Cloudflare.

A newer addition is the AI coding assistant skills, installed with the skills package.

bash
npx skills install cloudflare/chanfana

There is one skill available, write-endpoints, described as a comprehensive guide for building OpenAPI endpoints with schema definition, request validation, CRUD operations and D1 integration. This is a documentation-as-installable-package approach: the guidance is distributed with the library rather than living in a wiki, and the repository ships the skills directory and an llms.txt file alongside the published files list, which suggests an intent that the documentation be readable by a language model as well as by a person.

The package is also shipped with the docs, the skills folder, AGENTS.md, the changelog and the licence in the published files, so an offline install of the tarball still contains the reference material.

Defining an endpoint as a class with a Zod schema

The minimal example in the README shows the shape of an endpoint, and it is worth reading in full because the structure explains the inference story.

ts
import { fromHono, OpenAPIRoute } from 'chanfana'
import { Hono } from 'hono'
import { z } from 'zod'

export class GetPageNumber extends OpenAPIRoute {

The route extends OpenAPIRoute and declares a schema property with request sections for params and query, each a Zod object.

ts
      params: z.object({
        id: z.string().min(2).max(10),
      }),
      query: z.object({
        page: z.number().int().min(0).max(20),
      }),

Then the handler calls getValidatedData with the type of its own schema, which is what gives the handler its typed values without casting.

ts
    const data = await this.getValidatedData<typeof this.schema>()

The bindings type is declared alongside, and the router is wired up at the bottom with fromHono and a get registration that also registers the route in Hono.

ts
const app = new Hono<{ Bindings: Env }>()
const openapi = fromHono(app)
openapi.get('/entry/:id', GetPageNumber)
export default app

So there are three moving parts: a class per endpoint, a registry bound to the router, and a call that registers both the schema and the route. The comment in the README notes that registering the OpenAPI endpoints also registers the routes in Hono, which is the convenience that makes the class approach worthwhile.

The CLI and how the schema gets extracted

The CLI exists to produce a static schema file, and the README is explicit about the intended use: generating a static schema file for CI and CD pipelines.

bash
npx chanfana

The mechanism is worth knowing, because it explains the trade-offs. The command starts your worker with wrangler dev, fetches the schema from the openapi.json path, and saves it to schema.json. So the CLI boots a real worker, which means the schema is produced by running the application rather than by static analysis of the source.

That has a clear benefit and a clear cost. The benefit is that the extracted document is exactly what the running service serves, including anything computed at startup. The cost is that extraction requires a working wrangler environment and a worker that starts, so it needs the same environment variables and bindings the worker needs, and it will fail in CI if the worker cannot boot.

For a project that wants a checked-in schema artifact, the alternative is a step in the pipeline that runs the CLI and commits or publishes the result. The Cloudflare template project does something similar with its auto-generated docs at the api/docs path, so a fresh project gets documentation without any setup.

Scaffolding a project and the template's Task API

There are two ways to start. The first is the deploy button for Cloudflare, which links directly to the template directory in the repository. The second is the create-cloudflare CLI locally.

bash
npm create cloudflare@latest -- --template https://github.com/cloudflare/chanfana/tree/main/template

What the template contains is specified in the README, and it is a useful reference for what a complete chanfana project looks like. A complete Task API with Hono, D1 and Zod v4, full CRUD endpoints, a custom endpoint example, integration tests, and auto-generated docs at the api/docs path. The template has its own README with the full setup instructions.

The combination of D1, Zod v4 and full CRUD in one template is deliberate. It shows the library used the way it is meant to be used, with a real database behind the endpoints and a validation layer that reads the same schemas the OpenAPI document is generated from.

The docs site itself is built with VitePress, and the repository has scripts for deploying it to Cloudflare Pages under the chanfana project on the main branch, plus a docs dev server and a preview command.

Where chanfana is the wrong choice

The first limitation is the router dependency. The library is described as working with any router that the base router supports, and the adapter list names Hono and itty-router. A team on Express, Fastify or NestJS has to look for an adapter, and if there is none, the class-based endpoint model does not drop into a framework with its own routing conventions.

The second is that the class model is a constraint. Extending OpenAPIRoute means each endpoint is a class with a schema property and a handle method, which is fine in TypeScript and less natural in projects organised around plain functions. The README notes the ability to extend an existing application without touching old routes, so a mixed codebase works, but new endpoints in a codebase whose house style is functional will look foreign.

The third is the CLI needing a running worker. Extracting the schema boots the worker with wrangler dev, which means the schema extraction step inherits the worker's startup requirements, its bindings and its environment. In a CI pipeline that is more setup than a static analysis tool would ask for, and a schema generation step that can fail because a binding is missing is an awkward dependency.

The fourth is the Zod v4 requirement. The library is described as Zod v4 compatible, and the template pins Zod v4. A project on Zod 3 has to upgrade, which is usually fine but is a real dependency decision rather than a detail.

The fifth is the Cloudflare centre of gravity. The library is meant for Cloudflare Workers, the AI skills target Workers patterns with D1 integration, and the CLI is built around wrangler. It runs elsewhere, but the defaults and the examples assume Workers, and the author works at Cloudflare, so the roadmap will follow that platform.

Licence, release cadence and the cost of a schema library

The project is under the MIT licence, with the LICENSE file at the root and the package metadata declaring the same. The author and the Cloudflare affiliation are recorded in the manifest, and the repository carries a CODEOWNERS file, a changeset directory for release notes, an AGENTS.md and a llms.txt.

The release history is steady, with v3.4.0 in August 2026, v3.3.0 in March 2026 and v3.2.1 in February 2026, so the project is on a version 3 line with regular minor releases. The repository is not archived and the last push was on 2026-10-19, days before the current date, so maintenance is active.

The build and test setup is what a library of this kind should look like. The build removes the dist directory, type checks with tsc, and then bundles with tsup in both CommonJS and ESM formats with type declarations, keeping hono external so the host application controls that version. The test script type checks first and then runs vitest against a dedicated config, so a type error fails the suite rather than being hidden by the test runner. Linting is Biome, and the docs use VitePress with a Pages deploy script.

The cost to an adopting team is small in dependencies and larger in process. The dependency is one package plus Zod. The process cost is that the OpenAPI document becomes a build artifact rather than a hand-maintained file, which means the pipeline has to produce it, and the review of an API change happens in the code review of the Zod schema rather than in a separate spec diff.

Editorial conclusion

chanfana suits a team on Cloudflare Workers or any Hono or itty-router application that needs a real OpenAPI document and request validation without writing a spec by hand, since the schema comes from the same Zod definitions the runtime enforces. It does not suit an Express or Fastify codebase, since the router adapters are the integration point. Verify the Node version first, at 18 or above, and check the adapter list for your router before committing, since the library describes itself as working with any router the base supports.

Frequently asked questions

How do I add chanfana to a Hono project?

Install the package with npm i chanfana --save, then create a class that extends OpenAPIRoute with a schema property of Zod objects, build a router registry with fromHono, and register the endpoint with openapi.get and its path. The README's minimal example shows the whole flow, ending with exporting the Hono app.

How do I generate the OpenAPI schema.json for a chanfana project?

Run npx chanfana. The CLI starts your worker with wrangler dev, fetches the schema from the openapi.json path and saves it to schema.json. The README describes this as useful for generating a static schema file in a CI or CD pipeline.

Does chanfana work with routers other than Hono?

Yes. The README describes chanfana as adding OpenAPI schema generation and validation to any router, naming Hono and itty-router, and it runs on any runtime supported by the base router. It also says you can extend an existing Hono or itty-router application without touching old routes.

What Node version and peer requirements does chanfana have?

The package metadata requires Node 18 or above and the library is Zod v4 compatible with full TypeScript inference. The published package ships both ESM and CommonJS builds with separate type definitions, and keeps hono external so the host application controls that version.

Official sources

  1. cloudflare/chanfana on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cloudflare-chanfana.svg)](https://hysenlabs.com/projects/cloudflare-chanfana)

Was this useful?