Chi middleware is plainDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/go-chi/chi/llms.txt
Use this file to discover all available pages before exploring further.
net/http middleware — every middleware is just a function with the signature func(http.Handler) http.Handler. There is nothing chi-specific about the type; any middleware compatible with the Go standard library will work in a chi router without any adapters or wrappers.
The middleware signature
Every chi middleware is a function that accepts the next handler in the chain and returns a new handler that wraps it. When a request arrives, the outermost handler runs first; each layer can inspect or modify the request before callingnext.ServeHTTP, and optionally inspect or modify the response after it returns.
middleware.go
Applying middleware with r.Use()
r.Use() attaches one or more middlewares to the router’s stack. Every request that passes through that router will run all middlewares in the order they were registered — the first Use() call executes first, wrapping the outermost layer of the chain.
router_use.go
Middleware registered with
r.Use() applies to every route defined on that router and any sub-routers mounted beneath it. If you need to apply middleware to only a subset of routes, use r.With() or a scoped r.Group().Applying middleware inline with r.With()
r.With() creates a temporary inline router that applies the listed middlewares only to the single endpoint it wraps. The base router’s middleware stack still executes for every request; the With() middlewares run as an additional inner layer.
router_with.go
Middleware execution order
Chi builds a stack where the firstUse() call wraps the chain at the outermost position. Given:
execution_order.go
Request enters A
The first-registered middleware receives the request first. It can read or modify headers, the URL, or the context before passing control deeper.
A calls next — request enters B
B can further inspect or augment the request, optionally short-circuiting the chain by writing a response and returning without calling
next.ServeHTTP.A minimal custom middleware
The example below shows the canonical pattern for a middleware that stores a value on the request context and makes it available to every downstream handler.custom_middleware.go
The built-in middleware package
Chi ships an optionalmiddleware sub-package that provides a suite of production-ready handlers. Import it alongside the router:
import.go
func(http.Handler) http.Handler signature, you can freely mix it with any other compatible community middleware.
Built-In Middleware
Full reference for every handler in the
middleware package, grouped by category.Client IP Extraction
Safely resolve the real client IP address behind proxies and CDNs.
Custom Middleware
Patterns for writing your own middleware — context values, auth guards, and response capture.