Fuego
Golang Fuego - Web framework generating OpenAPI 3 spec from source code - Pluggable to existing Gin & Echo APIs
Install / Use
npx skills add go-fuego/fuegoInstalls into whichever agent you are using.
README
Fuego 🔥
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 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/httpcompatible (no lock-in): Fuego is built on top ofnet/http, so you can use anyhttp.Handlermiddleware or handler! Fuego also supportslog/slog,contextandhtml/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.InTransformandfuego.OutTransforminterfaces - also useful for custom validation - Middlewares: easily add a custom
net/httpmiddleware 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 liketemplorgomponents - 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.
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"}
</details>
From net/http to Fuego in 10s
https://github.com/go-fuego/fuego/assets/46993939/7438a71c-75a4-4e88-a584-71da6362c575
<details> <summary>Views</summary>Before
<img width="946" alt="image" src="https://github.com/go-fuego/fuego/assets/46993939/394fed17-a1e2-4b67-89b2-8e6c9eeb771b">After
<img width="1010" alt="image" src="https://github.com/go-fuego/fuego/assets/46993939/321088d7-bec4-46cc-a7ee-9a0fa45d7711">Diff
<img width="1413" alt="image" src="https://github.com/go-fuego/fuego/assets/46993939/18796a59-b2e4-4e01-81d1-88c581de3466">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 has contributed to this project! ❤️
<a href="https://github.com/go-fuego/fuego/graphs/contributors"> <img src="https://contrib.rocks/image?repo=go-fuego/fuego" alt="Graph of contributors" /> </a><small>Made with contrib.rocks</small>
Roadmap
See the board.
Disclaimer for experienced gophers
I know you might prefer to use net/http directly,
but if having a frame can convince my company to use
Go instead of Node, I'm happy to use it.
License
Related Skills
career-ops
63.2kOpen-source AI job search: scan job portals, evaluate listings with a structured A-F rubric into a 1.0-5.0 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)
gin-vue-admin
24.9k🚀Vite+Vue3+Gin拥有AI辅助的基础开发平台,企业级业务AI+开发解决方案,内置mcp辅助服务,内置skills管理,支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器、表单生成器和可配置的导入导出等开发必备功能。
kubeshark
12.0keBPF-powered network observability for Kubernetes. Indexes L4/L7 traffic with full K8s context, decrypts TLS without keys. Queryable by AI agents via MCP and humans via dashboard.
loupe
22Open-source CLI that measures AI coding-assistant impact (Claude Code, Copilot, Cursor, Aider) across Bitbucket+Jira, GitHub, GitLab, Azure DevOps, or Linear — and renders a reveal.js exec deck. Runs locally, no SaaS, no data leaves your environment.
