rgoussu@goussu: ~/library/go/web-frameworks
~/library/go/web-frameworks cat web-frameworks.md

Go web frameworks — the landscape

# How Go's stdlib-first web culture shapes the field — net/http, thin routers like chi, full frameworks Gin and Echo, and the fasthttp outlier Fiber.

Conceptsaved 2026-08-09 #go#frameworks#web#http#gin#echo#fiber

Overview

Go's web ecosystem is the inverse of the JVM's: the standard library is the framework. net/http ships a production-grade server, client, and router, and since Go 1.22 the enhanced ServeMux (method matching plus {wildcard} path patterns) erased much of the reason third-party routers existed. What remains stratifies into three tiers: thin routers (chi, gorilla/mux, httprouter) that add ergonomics on top of the stdlib http.Handler contract; full frameworks (Gin, Echo) that trade that contract for a richer context object, binding, and rendering; and Fiber, the deliberate outlier that abandons net/http entirely for fasthttp in pursuit of raw throughput.

Key points

  • net/http is the baseline, not a toy: sane concurrency (goroutine per connection), HTTP/2, graceful shutdown. Many production services need nothing else.
  • Go 1.22 ServeMux: mux.Handle("GET /items/{id}", h) — method routing, wildcards, {path...} remainders, and most-specific-wins precedence, all in the stdlib.
  • chi is the idiomatic thin router: 100% http.Handler/http.HandlerFunc, middleware as plain func(http.Handler) http.Handler, sub-routers, zero lock-in.
  • gorilla/mux: the historical default; archived in December 2022, revived under new maintainers in 2023 — a cautionary tale about depending on single-maintainer routers.
  • httprouter: the radix-tree speed pioneer (its router lives on inside Gin); its own handler signature makes it less stdlib-composable.
  • Gin and Echo occupy the same niche: batteries included — binding, validation (go-playground/validator), render helpers, big middleware catalogues — behind their own Context type, while remaining ServeHTTP-compatible at the outer edge.
  • Fiber swaps net/http for fasthttp: Express-like API and top benchmark numbers, at the cost of http.Handler interop and a recycled context that forbids retaining references.
  • Default advice: start stdlib (+ chi if route trees get deep); reach for Gin/Echo when the team wants conventions; reach for Fiber only with a measured throughput case.

Details

Comparison

net/http (1.22+) chi Gin Echo Fiber
Stdlib compatibility Is the stdlib Pure http.Handler throughout Own gin.Context; engine is ServeHTTP-compatible Own echo.Context; ships WrapHandler/WrapMiddleware adapters None — fasthttp; adaptor shim only
Router features Method + {wildcard}/{path...} patterns, precedence rules Same contract + sub-routers, mounting, route groups Radix tree (httprouter lineage), groups, param routes Radix tree, groups, param routes Radix tree, Express-style :param
Middleware model Decorator: func(http.Handler) http.Handler Stdlib decorators + curated chi/middleware set gin.HandlerFunc chain with c.Next()/c.Abort() echo.MiddlewareFunc chain + stdlib adapters fiber.Handler chain with c.Next()
Binding / validation Manual (encoding/json + your own checks) Manual (bring your own) ShouldBind* + go-playground/validator built in Bind + pluggable Validator hook BodyParser + bring your own validator
Performance posture Fast enough for almost everything Negligible overhead over stdlib Low-alloc routing; marketing leans on benchmarks Comparable to Gin Fastest in micro-benchmarks (fasthttp, zero-alloc claims)
Sweet spot Default choice; small services, full control REST APIs with deep route trees, stdlib purists Teams wanting Rails-ish conventions fast Same as Gin, tidier error handling Extreme-throughput micro-services that accept the trade

Contrast with the JVM

The Java framework landscape is framework-centric because the JDK offers no batteries: no production HTTP server story equivalent to net/http, so Spring, Quarkus and Micronaut each supply DI, configuration, and the server itself, and the interesting question becomes which specification (Jakarta EE, MicroProfile) each one implements. In Go the stdlib interfaces play the role of those specs — http.Handler is the contract, and frameworks are judged by whether they honor or replace it. That question gets its own note: who honors what.

Deep dives: net/http, Gin, Echo, Fiber.

Related