fuego is a free, open source api development & testing project written in Go and released under MIT. It has 1,775 GitHub stars, 129 forks and 18 open issues, and was last pushed 3 days ago. On this registry it ranks #122 of 178 tracked projects in API Development & Testing, with 5 head-to-head comparisons available.

What is fuego?

Fuego is an MIT-licensed, production-ready Go web framework that generates an OpenAPI 3 specification directly from source code, aimed at Go developers building HTTP APIs and web applications who want their documentation to stay in sync with their handlers.

What it is

Fuego is a Go API framework that lives in the standard net/http ecosystem and derives OpenAPI 3 documentation from the code itself. Routes are declared with typed handlers such as fuego.Get, fuego.Post and fuego.ContextWithBody[T], and the framework reads those signatures and struct tags to produce the specification. The README is explicit that the documentation is generated from code, not from comments and not from YAML files. The project also covers the surrounding work of an API server: routing, request serialization, validation, error handling and rendering.

The concrete problem it solves is documentation drift and the boilerplate that causes it. Writers of Go APIs historically maintained a separate OpenAPI description by hand, or annotated handlers with comments that a generator later parsed. Both approaches duplicate the truth already present in handler signatures and struct definitions. The README argues that older frameworks such as Chi, Gin, Fiber and Echo were designed before generics, so their current APIs cannot deduce OpenAPI types from signatures; Fuego was built to do exactly that. It is inspired by Nest and supports log/slog, context and html/template.

Key capabilities

  • Automatic OpenAPI 3 generation from typed handler signatures rather than from comments or YAML files.
  • 100% net/http compatibility, so any http.Handler middleware or handler can be used without lock-in.
  • Routing built on the Go 1.22 net/http router, with route grouping and middleware support.
  • Serialization and deserialization of JSON, XML and HTML Forms driven by user-provided structs.
  • Validation through a fast validator based on go-playground/validator, including validate:"required" style struct tags.
  • Transformation hooks through the fuego.InTransform and fuego.OutTransform interfaces, usable for custom validation.
  • Centralized error handling using the standard RFC 9457 problem-details format.
  • Rendering with html/template, or with a-h/templ and maragudk/gomponents instead.
  • Adaptors that plug Fuego into an existing Gin or Echo server to generate OpenAPI documentation for it.
  • OpenAPI tuning through the github.com/go-fuego/fuego/option and github.com/go-fuego/fuego/param packages.

Who uses it and how

  • Go teams starting a new API who want OpenAPI output without maintaining a parallel specification file.
  • Teams with an existing Gin or Echo service who adopt the adaptors first, gaining generated OpenAPI documentation without rewriting their routing.
  • Developers building server-rendered applications alongside APIs, using html/template, templ or gomponents rather than a separate frontend stack.
  • Projects that need to keep using existing net/http middleware, since Fuego is built on top of net/http rather than replacing it.
  • The repository's own examples/full-app-gourmet is a working reference application, and it runs live at https://gourmet.quimerch.com.

Getting started

The framework is imported from the Go module path github.com/go-fuego/fuego; the minimal program calls fuego.NewServer(), registers a route such as fuego.Get(s, "/", handler), and starts the server with s.Run(). The homepage is https://go-fuego.dev/.

How it compares

Among the tools named in the project's own reasoning, Gin, Echo, Chi and Fiber are the closest peers, and Fuego's stated differentiator is that their current APIs cannot deduce OpenAPI types from handler signatures while Fuego can. Those frameworks remain valid choices for applications that do not need generated documentation, and Fuego deliberately keeps them reachable through net/http compatibility and through dedicated Gin and Echo adaptors. Fuego is the newer and smaller project by adoption, with 1,775 stars, 129 forks and 18 open issues.

When to use it — and when not to

Choose Fuego when the API is written in Go, the team wants the OpenAPI document to be a product of the code, and standard net/http middleware must keep working. Be aware that code-first generation is a commitment as well as a benefit: teams with an established YAML-first or comment-annotation documentation pipeline have to move that workflow into code, and the router is built on the Go 1.22 net/http router, so older Go toolchains are not a target. Teams not writing Go, or those who prefer to author the specification by hand and treat it as the source of truth, should look elsewhere.

project readme (upstream, from github) — read inline

Fuego 🔥

Go Reference Go Report Card Coverage Status CodSpeed Badge Discord Gophers

The framework for busy Go developers

🚀 Explore and contribute to our 2025 Roadmap! 🚀

Production-ready Go API framework generating OpenAPI documentation from code. Inspired by Nest, built for Go developers.

Also empowers templating with html/template, a-h/templ and maragudk/gomponents: see the example running live.

Why Fuego?

Chi, Gin, Fiber and Echo are great frameworks. But since they were designed a long time ago, [their current API does not allow them][gin-gonic-issue] to deduce OpenAPI types from signatures, things that are now possible with generics. Fuego offers a lot of "modern Go based" features that make it easy to develop APIs and web applications.

Features

  • OpenAPI: Fuego automatically generates OpenAPI documentation from code - not from comments nor YAML files!
  • 100% net/http compatible (no lock-in): Fuego is built on top of net/http, so you can use any http.Handler middleware or handler! Fuego also supports log/slog, context and html/template.
  • Routing: Fuego router is based on Go 1.22 net/http, with grouping and middleware support
  • Serialization/Deserialization: Fuego automatically serializes and deserializes JSON, XML and HTML Forms based on user-provided structs (or not, if you want to do it yourself)
  • Validation: Fuego provides a simple and fast validator based on go-playground/validator
  • Transformation: easily transform your data by implementing the fuego.InTransform and fuego.OutTransform interfaces - also useful for custom validation
  • Middlewares: easily add a custom net/http middleware or use the provided middlewares.
  • Error handling: Fuego provides centralized error handling with the standard RFC 9457.
  • Rendering: Fuego provides a simple and fast rendering system based on html/template - you can still also use your own template system like templ or gomponents
  • Adaptors: Fuego can be plugged to an existing Gin or Echo server to generate OpenAPI documentation

Examples

Hello World

package main

import "github.com/go-fuego/fuego"

func main() {
	s := fuego.NewServer()

	fuego.Get(s, "/", func(c fuego.ContextNoBody) (string, error) {
		return "Hello, World!", nil
	})

	s.Run()
}

Simple POST

package main

import "github.com/go-fuego/fuego"

type MyInput struct {
	Name string `json:"name" validate:"required"`
}

type MyOutput struct {
	Message string `json:"message"`
}

func main() {
	s := fuego.NewServer()

	// Automatically generates OpenAPI documentation for this route
	fuego.Post(s, "/user/{user}", myController)

	s.Run()
}

func myController(c fuego.ContextWithBody[MyInput]) (*MyOutput, error) {
	body, err := c.Body()
	if err != nil {
		return nil, err
	}

	return &MyOutput{Message: "Hello, " + body.Name}, nil
}

With transformation & custom validation

type MyInput struct {
	Name string `json:"name" validate:"required"`
}

// Will be called just before returning c.Body()
func (r *MyInput) InTransform(context.Context) error {
	r.Name = strings.ToLower(r.Name)

	if r.Name == "fuego" {
		return errors.New("fuego is not a valid name for this input")
	}

	return nil
}

More OpenAPI documentation

package main

import (
	"github.com/go-fuego/fuego"
	"github.com/go-fuego/fuego/option"
	"github.com/go-fuego/fuego/param"
)

func main() {
	s := fuego.NewServer()

	// Custom OpenAPI options
	fuego.Post(s, "/", myController,
		option.Description("This route does something..."),
		option.Summary("This is my summary"),
		option.Tags("MyTag"), // A tag is set by default according to the return type (can be deactivated)
		option.Deprecated(),  // Marks the route as deprecated in the OpenAPI spec

		option.Query("name", "Declares a query parameter with default value", param.Default("Carmack")),
		option.Header("Authorization", "Bearer token", param.Required()),
		optionPagination,
		optionCustomBehavior,
	)

	s.Run()
}

var optionPagination = option.Group(
	option.QueryInt("page", "Page number", param.Default(1), param.Example("1st page", 1), param.Example("42nd page", 42)),
	option.QueryInt("perPage", "Number of items per page"),
)

var optionCustomBehavior = func(r *fuego.BaseRoute) {
	r.XXX = "YYY"
}

Std lib compatibility

package main

import (
	"net/http"

	"github.com/go-fuego/fuego"
)

func main() {
	s := fuego.NewServer()

	// Standard net/http middleware
	fuego.Use(s, func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("X-Hello", "World")
			next.ServeHTTP(w, r)
		})
	})

	// Standard net/http handler with automatic OpenAPI route declaration
	fuego.GetStd(s, "/std", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello, World!"))
	})

	s.Run()
}

Real-world examples

Please see the /examples folder for more examples.

All features
package main

import (
	"context"
	"errors"
	"net/http"
	"strings"

	chiMiddleware "github.com/go-chi/chi/v5/middleware"
	"github.com/go-fuego/fuego"
	"github.com/rs/cors"
)

type Received struct {
	Name string `json:"name" validate:"required"`
}

type MyResponse struct {
	Message       string `json:"message"`
	BestFramework string `json:"best"`
}

func main() {
	s := fuego.NewServer(
		fuego.WithAddr("localhost:8088"),
	)

	fuego.Use(s, cors.Default().Handler)
	fuego.Use(s, chiMiddleware.Compress(5, "text/html", "text/css"))

	// Fuego 🔥 handler with automatic OpenAPI generation, validation, (de)serialization and error handling
	fuego.Post(s, "/", func(c fuego.ContextWithBody[Received]) (MyResponse, error) {
		data, err := c.Body()
		if err != nil {
			return MyResponse{}, err
		}

		c.Response().Header().Set("X-Hello", "World")

		return MyResponse{
			Message:       "Hello, " + data.Name,
			BestFramework: "Fuego!",
		}, nil
	})

	// Standard net/http handler with automatic OpenAPI route declaration
	fuego.GetStd(s, "/std", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello, World!"))
	})

	s.Run()
}

// InTransform will be called when using c.Body().
// It can be used to transform the entity and raise custom errors
func (r *Received) InTransform(context.Context) error {
	r.Name = strings.ToLower(r.Name)
	if r.Name == "fuego" {
		return errors.New("fuego is not a name")
	}
	return nil
}

// OutTransform will be called before sending data
func (r *MyResponse) OutTransform(context.Context) error {
	r.Message = strings.ToUpper(r.Message)
	return nil
}
curl http://localhost:8088/std
# Hello, World!
curl http://localhost:8088 -X POST -d '{"name": "Your Name"}' -H 'Content-Type: application/json'
# {"message":"HELLO, YOUR NAME","best":"Fuego!"}
curl http://localhost:8088 -X POST -d '{"name": "Fuego"}' -H 'Content-Type: application/json'
# {"error":"cannot transform request body: cannot transform request body: fuego is not a name"}

From net/http to Fuego in 10s

Views

Before

image
After
image
Diff
image
Benefits of using Fuego views (controllers returning HTML)
  • Never forget to return after an error
  • OpenAPI schema generated, listing all the routes
  • Deserialization and validation are easier
  • Transition to Fuego is easy and fast

Contributing

See the contributing guide. Thanks to [everyone who

readme truncated — read the full docs on github

Frequently asked questions

Is fuego free to use?

fuego is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does fuego do?

Golang Fuego - Web framework generating OpenAPI 3 spec from source code - Pluggable to existing Gin & Echo APIs

What is fuego written in?

fuego is primarily written in Go. Its source is publicly available at https://github.com/go-fuego/fuego, and it has 1,775 GitHub stars.