Skip to main content

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 :param and *param support, 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 :param syntax.
  • Middleware - Apply middleware globally or per-route with chain dispatch.
  • Context pooling - Each request reuses a Ctx from sync.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/slog with 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/http types

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()
}