An elegant, lightweight, and beautiful OpenAPI documentation renderer built for Go developers
English | 简体中文
Coco is an elegant, lightweight, and beautiful Go library that renders OpenAPI/Swagger specifications into stunning interactive API documentation. Zero dependencies, single-file bundle, perfectly embedded into Go binaries. Supports OpenAPI 2.0 and 3.0+ specifications with seamless integration into any Go web framework.
- Elegant DX - Minimal API design, integrate in just 30 seconds
- Beautiful UI - Built with Vue 3 + TailwindCSS, supports automatic light/dark theme switching
- Framework Agnostic - Works with all Go web frameworks (Gin, Echo, Fiber, Chi, net/http, etc.)
- Feature Complete - Built-in API testing, spec export, request history, internationalization, and more
- Internationalization - Built-in English and Chinese support, extensible for more languages
- Zero Dependencies - Pure Go implementation, frontend assets fully embedded, no external tools required
- Framework Agnostic - Compatible with all Go web frameworks (Gin, Echo, Fiber, Chi, net/http, etc.)
- Flexible Configuration - Rich configuration options to meet various customization needs
- API Testing - Built-in interactive debug panel for instant API testing
- Spec Export - One-click export of OpenAPI/Swagger specification files
- Request History - Automatically saves debug history for easy review and reuse
- High Performance - Embedded static assets, single-file bundle, no additional HTTP requests
go get github.com/leehainuo/cocoStep 1: Install Swag
go install github.com/swaggo/swag/cmd/swag@latestStep 2: Add annotations to your code
package main
import (
"net/http"
"github.com/leehainuo/coco"
)
// @title My API
// @version 1.0
// @description This is a sample API
// @host localhost:8000
// @BasePath /api
func main() {
mux := http.NewServeMux()
// Your API routes
mux.HandleFunc("/api/hello", handleHello)
// Mount Coco docs (Swag generates docs/swagger.json)
mux.Handle("/docs/", coco.New("./docs/swagger.json"))
http.ListenAndServe(":8000", mux)
}
// @Summary Hello endpoint
// @Description Returns a greeting message
// @Tags example
// @Accept json
// @Produce json
// @Success 200 {string} string "Hello, World!"
// @Router /hello [get]
func handleHello(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
}Step 3: Generate docs and run
# Generate OpenAPI documentation
swag init
# Run your application
go run main.goStep 4: View your docs
Open your browser and visit http://localhost:8000/docs/ to see your beautiful API documentation!
Load from local file
handler := coco.New("./openapi.json")Load from URL
handler := coco.New("", coco.SpecURL("https://example.com/openapi.json"))Load from byte array
handler := coco.New("", coco.Spec(specBytes))For more configuration and integration options, see Full Documentation
package main
import (
"net/http"
"github.com/leehainuo/coco"
)
func main() {
mux := http.NewServeMux()
// Your API routes
mux.HandleFunc("/api/users", handleUsers)
// Mount documentation
mux.Handle("/docs/", coco.New("./openapi.json",
coco.Title("User API"),
))
http.ListenAndServe(":8000", mux)
}package main
import (
"github.com/gin-gonic/gin"
"github.com/leehainuo/coco"
)
func main() {
r := gin.Default()
// Your API routes
r.GET("/api/users", getUsers)
// Mount documentation
r.Any("/docs/*any", gin.WrapH(coco.New("./openapi.json",
coco.Title("User API"),
)))
r.Run(":8000")
}package main
import (
"github.com/labstack/echo/v4"
"github.com/leehainuo/coco"
)
func main() {
e := echo.New()
// Your API routes
e.GET("/api/users", getUsers)
// Mount documentation
e.Any("/docs/*", echo.WrapHandler(coco.New("./openapi.json",
coco.Title("User API"),
)))
e.Start(":8000")
}package main
import (
"net/http"
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/adaptor"
"github.com/leehainuo/coco"
)
func main() {
app := fiber.New()
// Your API routes
app.Get("/api/users", getUsers)
// Mount documentation
handler := coco.New("./openapi.json",
coco.Title("User API"),
)
app.All("/docs/*", adaptor.HTTPHandler(http.HandlerFunc(handler.ServeHTTP)))
app.Listen(":8000")
}package main
import (
"net/http"
"github.com/go-chi/chi/v5"
"github.com/leehainuo/coco"
)
func main() {
r := chi.NewRouter()
// Your API routes
r.Get("/api/users", getUsers)
// Mount documentation
r.HandleFunc("/docs/*", func(w http.ResponseWriter, req *http.Request) {
handler := coco.New("./openapi.json",
coco.Title("User API"),
)
handler.ServeHTTP(w, req)
})
http.ListenAndServe(":8000", r)
}// Load from file path
coco.New("./openapi.json")
// Load from byte array
coco.New("", coco.Spec(specBytes))
// Load from remote URL
coco.New("", coco.SpecURL("https://example.com/openapi.json"))// Set document title
coco.Title("My API Documentation")
// Set theme: "light", "dark", "auto"
coco.Theme("dark")
// Set language: "en", "zh"
coco.Lang("en")// Enable/disable debug panel (enabled by default)
coco.EnableDebug(true)
// Enable/disable export feature (enabled by default)
coco.EnableExport(true)
// Enable/disable history (enabled by default)
coco.EnableHistory(true)package main
import (
"context"
"net/http"
"github.com/danielgtaylor/huma/v2"
"github.com/danielgtaylor/huma/v2/adapters/humago"
"github.com/leehainuo/coco"
)
func main() {
mux := http.NewServeMux()
api := humago.New(mux, huma.DefaultConfig("My API", "1.0.0"))
// Register your API
huma.Register(api, huma.Operation{
OperationID: "get-users",
Method: http.MethodGet,
Path: "/api/users",
Summary: "Get users",
}, func(ctx context.Context, input *struct{}) (*struct{}, error) {
return &struct{}{}, nil
})
// Get OpenAPI spec and mount documentation
spec, _ := api.OpenAPI().MarshalJSON()
mux.Handle("/docs/", coco.New("",
coco.Spec(spec),
coco.Title("My API - Huma"),
))
http.ListenAndServe(":8000", mux)
}package main
import (
"net/http"
"github.com/leehainuo/coco"
)
// @title My API
// @version 1.0
// @description This is my API
// @host localhost:8000
// @BasePath /api
func main() {
mux := http.NewServeMux()
// Your API routes
mux.HandleFunc("/api/users", getUsers)
// Mount documentation (swag generates docs/swagger.json)
mux.Handle("/docs/", coco.New("./docs/swagger.json",
coco.Title("My API - Swag"),
))
http.ListenAndServe(":8000", mux)
}Generate documentation before running:
swag initlight- Light themedark- Dark themeauto- Follow system (default)
en- English (default)zh- Chinese
Users can switch themes and languages anytime in the top-right corner of the interface.
- English Docs: docs/en/ - Complete English documentation
- 中文文档: docs/zh/ - 完整的中文使用指南
- Documentation Home: docs/ - Choose your language / 选择你的语言
Check the example/framework directory for complete examples:
- net/http - Standard library examples
- Gin - Gin framework integration
- Echo - Echo framework integration
- Fiber - Fiber v3 framework integration
- Chi - Chi router integration
Each framework provides examples for both Huma and Swag OpenAPI generation methods.
Contributions, issues, and suggestions are welcome!
If you're using Coco or find it helpful, please give us a Star ⭐
MIT License - See LICENSE file for details
If you like this project or are using it to learn or build your solution, please give it a Star to get updates on new releases. Your support matters!
Made with ❤️ by leehainuo


