๐ŸŒฌ๏ธ Breeze docs

Getting started

Breeze is a modern, high-performance Go web framework for people who want speed and a real toolbox: a router, WebSockets, request binding, an OpenAPI generator, a live developer dashboard, an event bus, durable workflows, distributed tracing across services, a JSON-RPC server, an AI-agent control plane โ€” all first-party, all documented, none of it bolted on as an afterthought.

It is built on gnet: one event loop per core, zero-copy where it counts.

Installation

Requires Go 1.25.13 or later.

go get  github.com/nelthaarion/breeze/v2

This pulls in gnet v2 for the event loop, go-json for fast marshaling, brotli for compression, and golang-jwt for authentication. Nothing else โ€” every other subsystem is an opt-in subpackage you import only if you use it.

Quick start

A complete server in under 20 lines:

package main

import (
	"runtime"

	"github.com/nelthaarion/breeze/v2"
	middleware "github.com/nelthaarion/breeze/v2/middlewares"
)

func main() {
	router := breeze.NewRouter()
	router.Use(middleware.RecoveryMiddleware())
	router.Use(middleware.LoggingMiddleware())

	router.Handle(breeze.GET, "/", func(ctx *breeze.Context) error {
		return ctx.JSON(map[string]string{"status": "ok"})
	})
	router.Handle(breeze.GET, "/users/:id", func(ctx *breeze.Context) error {
		return ctx.JSON(map[string]string{"id": ctx.Param("id")})
	})

	pool := breeze.NewEventLoopWorkerPool(runtime.NumCPU())
	app := breeze.New(router, pool)
	app.Run(3000, true) // port, multiCore
}
go run main.go
# curl http://localhost:3000/        โ†’ {"status":"ok"}
# curl http://localhost:3000/users/42 โ†’ {"id":"42"}

Two building blocks appear in every Breeze program: a *breeze.Router that maps methods and paths to handlers, and a *breeze.WorkerPool that the *breeze.Breeze server uses for anything that blocks. NewEventLoopWorkerPool sizes the pool to the number of CPUs, which is the right default for CPU-bound or short blocking work.

Graceful shutdown

Run blocks until the server is stopped; Stop stops it. The contract mirrors net/http.Server.Shutdown โ€” a context bounds how long in-flight work is given to finish, and whatever is left is closed:

app := breeze.New(router, pool)

go func() {
	if err := app.Run(3000, true); err != nil {
		log.Printf("breeze: %v", err)
	}
}()

// SIGINT / SIGTERM
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
<-sig

ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
if err := app.Stop(ctx); err != nil {
	log.Printf("breeze: unclean shutdown: %v", err)
}
pool.Shutdown(ctx) // Stop does not touch a pool it did not create

What Stop does, in order:

StepBehaviour
1New connections are refused immediately
2Every WebSocket connection gets a Close frame with 1001 going away, and its handler's OnClose runs through the connection's ordered queue
3Work already dispatched to the pool โ€” blocking routes, WebSocket callbacks โ€” is given until ctx is done
4The listener closes, anything still connected is force-closed, and Run returns

Stop returns nil on a clean stop, ctx.Err() when step 3 ran out of time (the teardown still happens), and breeze.ErrNotRunning when there was nothing to stop. It is idempotent, and when it returns, Run's goroutine has already exited. Each *Breeze holds its own engine, so two servers in one process stop independently; a stopped one is not reusable โ€” Run then returns breeze.ErrServerStopped.

Docker

docker build -t breeze-example .
docker run --rm -p 3000:3000 breeze-example
# or
docker compose up --build

Breeze itself is a library โ€” point BREEZE_TARGET at any main package in your module to containerize your app:

docker build --build-arg BREEZE_TARGET=./cmd/dashboard-example -t my-app .

Where to go next

Generated documentation for the Breeze framework ยท built with SvelteKit, fully static.