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", "custom"
coco.Lang("en")
// Add a custom language from a translation file (optional)
coco.I18n("./i18n.fr.json")// 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- Chinesecustom- A custom language loaded from your owni18n.json
Users can switch themes and languages anytime in the top-right corner of the interface.
To add a language beyond the built-in English and Chinese, provide a translation
file via coco.I18n (file), coco.I18nData (bytes) or coco.I18nURL (URL), then
select it with coco.Lang("custom"). See the Configuration Guide for details.
- Quick Start Guide
- Configuration Guide
- Framework Integration Guide
- OpenAPI Generation Guide
- API Reference
- Documentation Home / 文档首页
- 简体中文
- Basic examples: remote, embedded, and local specifications, net/http, and custom languages.
- Framework examples: net/http, Gin, Echo, Fiber v3, and Chi, each with Huma and Swag integrations.
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


