Huma: An OpenAPI 3.1 Layer for Go APIs, Not Another Router
Huma REST/HTTP API Framework for Golang with OpenAPI 3.1
At a glance
- What is it?
- Huma is a Go framework that generates OpenAPI 3.1 and JSON Schema from annotated Go types while leaving the router choice to you. It suits teams that already have a chi, Gin, Echo or Fiber service and want documentation that cannot drift.
- Who is it for?
- Adopt Huma if you have a Go HTTP service and want its OpenAPI document generated from the same types that validate requests, especially on a router you already run. Skip it if you want the framework to own routing, templating and the whole application lifecycle, or if your handlers are not expressible as typed input and output structs.
- 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 4 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Huma targets: documentation that drifts from handler code
In a typical Go service, the handler signature, the validation rules and the OpenAPI file are three separate artifacts. The handler is compiled, the validation is hand-written or bolted on, and the spec is edited by hand until someone forgets. Huma's stated goal is documentation that cannot get out of date, achieved by deriving JSON Schema from annotated Go types and generating the OpenAPI 3.1 document from the same declarations that bind request parameters, bodies and response headers.
The intended audience is Go developers building REST or HTTP RPC backends, particularly teams with services already in production. The README frames the first goal as incremental adoption: bring your own router, middleware, logging and metrics, and use the OpenAPI and JSON Schema layer to document routes that already exist. That is a different posture from a full framework. Huma is not trying to own your main function. It is trying to own the contract between your handler signatures and the generated specification, and to add guard rails around the mistakes that contract tends to produce.
How Huma works: typed operations over your existing router
The mechanism is a declarative layer placed on top of a router. You register an operation with Huma, and the operation carries a generic input type and a generic output type. The input type is where path, query, header and cookie parameters live alongside the request body, and the output type is where responses and response headers live. Huma reads those Go types, builds JSON Schema from them, validates incoming requests against that schema, and emits the corresponding OpenAPI 3.1 document.
Because the router is supplied rather than built in, the adapters directory and the go.mod dependencies show the surface: chi, Gin, Echo v4 and v5, Fiber v2 and v3, gorilla/mux, httprouter and bunrouter are all listed as requirements, and the README notes support for Go 1.22+ routers. The go.mod declares go 1.25.0, so the module itself is built against a recent toolchain even though the router integrations are broader.
Several behaviours sit in the default configuration rather than in user code. Errors are returned as RFC 9457 problem details with the application/problem+json content type by default, and the README says this can be changed. Content negotiation between JSON and optionally CBOR happens through the Accept header with the default config. Per-operation request size limits have what the README calls sane defaults. Conditional request helpers exist for headers such as If-Match and If-Unmodified-Since. There is also an autopatch package in the repository root, which corresponds to the optional automatic generation of PATCH operations supporting RFC 7386 JSON Merge Patch, RFC 6902 JSON Patch and shorthand patches.
Documentation rendering uses Stoplight Elements, and the generated specification is the integration point with the wider tooling ecosystem: mocks through API Sprout or Prism, SDKs through OpenAPI Generator or oapi-codegen, and command-line clients through Restish.
Installing Huma and registering a first operation
The README has an Install section, and the module path in go.mod is github.com/danielgtaylor/huma/v2, so the package is fetched with the Go toolchain in the usual way. In a module that already has a router dependency, the command is:
go get github.com/danielgtaylor/huma/v2The repository ships an examples directory with runnable projects, including greet, cookies, custom-error, fields, html, oneof-response, param-reuse, protodemo, renaming-type, resolver and spec-cmd. The greet example is the smallest entry point, and its go.mod is separate from the root module, so it can be run from inside that directory. The general shape of a Huma program is a router, an adapter that wraps it, a huma.Register call that attaches the operation, and a listen call on the underlying router. The exact adapter constructor differs per router; the examples directory is the place to copy the one matching your stack, because the README does not inline a full program.
The command-line layer is optional and lives in the humacli package. The README states that it is configured via arguments or environment variables, and gives the example that a port can be set with -p 8000, --port=8000, or SERVICE_PORT=8000. Startup actions and graceful shutdown are described as built in. That means a service can get flag parsing, environment overrides and shutdown handling without pulling in a separate CLI framework, though cobra and pflag appear in go.mod as the underlying implementation.
Where Huma stops: routing, middleware and framework opinions
The most important limitation is the one that is also the design goal. Huma does not give you a router, and it does not give you middleware. If you are starting a project and want a single dependency that decides how requests are matched, how middleware is chained and how the server is structured, Huma leaves those decisions open, which means more assembly work before the first endpoint answers a request. The README is explicit that you bring your own router, middleware and logging or metrics.
A second constraint is that the declarative interface depends on expressing handlers as typed input and output structs. Handlers that do not fit that shape, for example streaming responses outside the sse package, long-lived connections, or endpoints whose payloads are not naturally described by Go types, will not get the same benefit from the schema generation. The repository does include an sse directory and an examples/sse entry, so server-sent events have support, but the general point stands: the value of the framework scales with how much of your API can be described by types.
Because the OpenAPI document is generated from those types, the specification is only as accurate as the annotations. A field that is not annotated will not appear in the schema, and a response that is not declared in the output type will not appear in the document. Huma removes the drift between handler and spec, but it does not remove the need to describe the API. It moves that description into the Go source. Teams that want to hand-write a specification first and generate server stubs from it are working in the opposite direction, and oapi-codegen is the tool for that workflow rather than Huma.
The project is MIT licensed, which is permissive and imposes no copyleft obligation on your service. That is worth stating plainly because the generated OpenAPI document and the Go types are both artifacts of your own code, and nothing in the licence reaches into them. This is a description of the licence text, not legal advice; if your organisation has specific requirements, the LICENSE.md file in the repository root is the authoritative source.
Huma compared with Gin and with spec-first code generation
The related searches around Huma versus Gin point at a real distinction. Gin is a router with a context object, middleware chaining and binding helpers. It owns the request lifecycle. Huma does not compete on that ground; the go.mod lists Gin as a dependency because Huma has an adapter for it. If you already run Gin, Huma sits on top and adds the typed operation layer and the generated specification. If you are choosing a router from scratch, Gin gives you routing and Huma gives you the contract layer, and you may end up using both.
The sharper comparison is with spec-first generation. With oapi-codegen or OpenAPI Generator, the OpenAPI document is the source of truth and Go code is produced from it. The document can be reviewed before any handler exists, and multiple languages can be generated from one file. The cost is a generation step in the build, a second artifact to keep in sync with hand-written handler logic, and a workflow where changing a field means editing YAML and regenerating. Huma inverts this: Go types are the source of truth and the document is an output. That is faster to iterate on inside a Go service and harder to share across languages. The README lists oapi-codegen and OpenAPI Generator as consumers of the generated spec, which is a reasonable middle path: define types in Go, generate the document, then generate clients from the document for other languages.
Maintenance, releases and upgrade cost
The repository is not archived, and the last push was on 2026-09-18. The most recent release listed is v2.39.1 from 2026-07-29, preceded by v2.39.0 on 2026-07-15 and v2.38.0 on 2026-05-15. The release cadence visible in that list is roughly every few weeks to two months, with patch releases in between.
The upgrade cost that matters most is the major version boundary. The module path is github.com/danielgtaylor/huma/v2, so the v2 line is what you import, and moving between minor versions within v2 is the normal upgrade path. The go.mod declares go 1.25.0, which means the module is built against a recent Go toolchain; if your project pins an older Go version, that is the first thing to check before adopting, because the toolchain directive is the clearest signal of the minimum the maintainers test against.
A second cost is the adapter surface. Huma depends on multiple routers at once, including Gin, chi, Echo v4 and v5, Fiber v2 and v3, gorilla/mux, httprouter and bunrouter. That breadth is convenient, but it also means the dependency graph of the module is larger than a single-router framework's. In practice you import the adapter you use, and the Go build only pulls what is reachable, but the go.sum in your project will grow when you add Huma to a service that did not already depend on those routers.
Editorial conclusion
Adopt Huma if you have a Go HTTP service and want its OpenAPI document generated from the same types that validate requests, especially on a router you already run. Skip it if you want the framework to own routing, templating and the whole application lifecycle, or if your handlers are not expressible as typed input and output structs. Before committing, check the adapters list in the repository for your router, confirm your Go version against the go.mod directive, and read how huma.Register is called in the examples directory for the closest match to your stack.
Frequently asked questions
What is the Huma API framework for Go?
Huma is a framework for building HTTP REST or RPC APIs in Go, described by OpenAPI 3.1 and JSON Schema. It provides a declarative interface on top of a router you choose, generating documentation from annotated Go types and validating input models automatically.
Does Huma work with Gin and Fiber?
Yes. The go.mod lists Gin, Fiber v2 and v3, chi, Echo v4 and v5, gorilla/mux, httprouter and bunrouter as dependencies, and the README describes bringing your own router as a core goal. The adapters directory contains the integration code for each.
What Go version does Huma require?
The module's go.mod declares go 1.25.0. The README also notes support for Go 1.22+ routers, which refers to the router implementations rather than the toolchain the module itself is built against.
Does Huma generate the OpenAPI specification automatically?
The README states that Huma generates OpenAPI for access to the surrounding tooling ecosystem, and that documentation cannot get out of date because it is derived from the annotated Go types used for input and output models. The document is an output of the type declarations, not a file you maintain by hand.
What licence does Huma use?
The repository is MIT licensed, with the licence text in LICENSE.md at the repository root.
Official sources
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.
[](https://hysenlabs.com/projects/danielgtaylor-huma)