-
Notifications
You must be signed in to change notification settings - Fork 0
Migration from Huma
MeGaNeKo edited this page Mar 20, 2026
·
1 revision
This guide covers the key changes when migrating from Huma v2 to Neoma.
| Huma v2 | Neoma |
|---|---|
github.com/danielgtaylor/huma/v2 |
github.com/MeGaNeKoS/neoma/neoma |
github.com/danielgtaylor/huma/v2/adapters/humachi |
github.com/MeGaNeKoS/neoma/adapters/neomachi/v5 |
github.com/danielgtaylor/huma/v2/humatest |
github.com/MeGaNeKoS/neoma/neomatest |
github.com/danielgtaylor/huma/v2/humacli |
github.com/MeGaNeKoS/neoma/neomacli |
github.com/danielgtaylor/huma/v2/sse |
github.com/MeGaNeKoS/neoma/sse |
| (no equivalent) | github.com/MeGaNeKoS/neoma/core |
| (no equivalent) | github.com/MeGaNeKoS/neoma/errors |
| (no equivalent) | github.com/MeGaNeKoS/neoma/middleware |
| (no equivalent) | github.com/MeGaNeKoS/neoma/pipeline |
Types like Context, Operation, Config, and Schema live in the core package. Registration functions (NewAPI, Register, Get, Post, etc.) live in the neoma package. There are no type aliases; import core directly for type references.
// Huma v2
var op huma.Operation
// Neoma
import "github.com/MeGaNeKoS/neoma/core"
var op core.Operation// Huma v2
router := chi.NewMux()
api := humachi.New(router, huma.DefaultConfig("My API", "1.0.0"))
// Neoma
router := chi.NewMux()
adapter := neomachi.NewAdapter(router)
config := neoma.DefaultConfig("My API", "1.0.0")
api := neoma.NewAPI(config, adapter)Huma v2 had a hardcoded error model. Neoma uses a pluggable ErrorHandler interface with two built-in implementations:
import "github.com/MeGaNeKoS/neoma/errors"
config.ErrorHandler = errors.NewRFC9457Handler() // RFC 9457 (default)
config.ErrorHandler = errors.NewNoopHandler() // No error schemaThe naming convention changed from status-code-in-name to descriptive names. Functions moved to the errors package:
| Huma v2 | Neoma |
|---|---|
huma.Error400BadRequest(msg) |
errors.ErrorBadRequest(msg) |
huma.Error401Unauthorized(msg) |
errors.ErrorUnauthorized(msg) |
huma.Error403Forbidden(msg) |
errors.ErrorForbidden(msg) |
huma.Error404NotFound(msg) |
errors.ErrorNotFound(msg) |
huma.Error409Conflict(msg) |
errors.ErrorConflict(msg) |
huma.Error422UnprocessableEntity(msg) |
errors.ErrorUnprocessableEntity(msg) |
huma.Error429TooManyRequests(msg) |
errors.ErrorTooManyRequests(msg) |
huma.Error500InternalServerError(msg) |
errors.ErrorInternalServerError(msg) |
Groups moved to the middleware package:
// Huma v2
grp := api.Group("/v1")
// Neoma
import "github.com/MeGaNeKoS/neoma/middleware"
grp := middleware.NewGroup(api, "/v1")The test API uses a generic Do method instead of per-method helpers:
// Huma v2
_, api := humatest.New(t, huma.DefaultConfig("Test", "1.0.0"))
resp := api.Get("/items")
// Neoma
_, api := neomatest.New(t)
resp := api.Do("GET", "/items")neomatest.New accepts an optional core.Config. Without one, it uses neoma.DefaultConfig("Test API", "1.0.0").
| Setting | Huma v2 | Neoma |
|---|---|---|
AllowAdditionalPropertiesByDefault |
false |
true |
FieldsOptionalByDefault |
false |
true |
| Docs path | /docs |
/public/docs |
| Area | Huma v2 | Neoma |
|---|---|---|
| Types | Root huma package |
core package (no aliases) |
| Registration | Root huma package |
neoma package |
| Adapter | humachi.New(router, config) |
neomachi.NewAdapter(router) + neoma.NewAPI(config, adapter)
|
| Errors | Hardcoded model | Pluggable ErrorHandler
|
| Error functions | huma.Error404NotFound |
errors.ErrorNotFound |
| Groups | api.Group("/v1") |
middleware.NewGroup(api, "/v1") |
| Test requests | api.Get("/path") |
api.Do("GET", "/path") |
| Internal spec | Not available | core.InternalSpecConfig |
| Pipeline | Not available |
pipeline package |
| Auto-discovery | Not available |
neoma-discover tool |
- Update
go.modto usegithub.com/MeGaNeKoS/neoma - Update all import paths (see table above)
- Change adapter construction to separate
NewAdapter+NewAPIcalls - Move error calls from
huma.Error*toerrors.Error*with new names - Update group creation from
api.Group()tomiddleware.NewGroup(api) - Replace test
api.Get/api.Postcalls withapi.Do("GET", ...) - If using custom error models, implement
core.ErrorHandler - Update docs path references from
/docsto/public/docs - Run tests to verify behavior