Introduction
Zen is a lightweight, high-performance HTTP microframework for Go built on a custom per-method radix tree router with zero-allocation path parameter extraction, delivering performance on par with popular Go frameworks.
Key Features
- Radix tree routing - Custom per-method radix tree router with
:paramand*paramsupport, backtracking for static-vs-param conflicts, and trailing-slash redirect. Zero allocations on all routing paths. - Path parameters - Access via
c.Param("name"). Supports both{param}and:paramsyntax. - Middleware - Apply middleware globally or per-route with chain dispatch.
- Context pooling - Each request reuses a
Ctxfromsync.Pool, minimizing allocations and GC pressure. - Request binding - Bind JSON, XML, form data, headers, query strings, and path parameters directly to Go structs using struct tags.
- Validation - Built-in struct validation wraps
go-playground/validator. Optional auto-validation after bind. - Response rendering - Render JSON, XML, HTML, plain text, streaming responses, file serving, and Server-Sent Events with a minimal API.
- OpenAPI documentation - Auto-generated OpenAPI 3.0.3 spec from routes and Go types, with Swagger UI, Scalar, or Redoc. Zero overhead when disabled (separate package). Configurable SwaggerUI init options.
- Auth - JWT, Basic Auth, API Key, Session, OAuth2, and OIDC authentication with role-based and permission-based access control.
- Graceful shutdown - Built-in signal handling (
SIGINT,SIGTERM) drains active connections before shutting down, with a configurable timeout. - Swappable logger - Structured logging via
log/slogwith configurable levels. Default logger writes to stderr.
Philosophy
- Minimal dependencies - core relies on
go-playground/validator/v10; optional packages add only what you import - Minimal API surface - just enough abstraction to be productive without hiding
net/http - Performance - comparable to hand-optimized handlers
- Go standard library first - middleware and handlers receive raw
net/httptypes
Quick Example
package main
import (
"github.com/Pavan-Silva/go-zen"
"github.com/Pavan-Silva/go-zen/middleware"
)
func main() {
r := zen.New(":8080")
r.Use(middleware.Recover)
r.Use(middleware.Logger)
r.GET("/hello", func(c *zen.Ctx) {
c.String(200, "Hello, World!")
})
r.GET("/users/{id}", func(c *zen.Ctx) {
id := c.Param("id")
c.JSON(200, map[string]string{"id": id})
})
r.Run()
}