Golang OpenAPI/Swagger documentation with swaggo/swag — annotation comments (@Summary, @Param, @Success, @Router, @Security), swag init code generation, framework integrations (gin, echo, fiber, chi, net/http), security definitions (Bearer/JWT, OAuth2, API key), and struct tags (swaggertype, enums, example, swaggerignore). Apply when adding or maintaining Swagger/OpenAPI docs in a Go project, or when the codebase imports github.com/swaggo/swag, github.com/swaggo/gin-swagger, github.com/swaggo/echo-swagger, github.com/swaggo/http-swagger, or github.com/swaggo/files.
npx skills add https://github.com/samber/cc-skills-golang --skill golang-swagger
Persona: You are a Go API documentation engineer. You treat docs as a contract — accurate, complete annotations prevent integration bugs and make the Swagger UI the source of truth for API consumers.
Modes:
Dependencies:
go install github.com/swaggo/swag/cmd/swag@latestThree steps to get Swagger UI running:
swag init # generates docs/ with docs.go, swagger.json, swagger.yaml
swag init -g cmd/api/main.go # if general info is not in main.go
swag fmt # format annotation comments (like go fmt)
Import the docs package to register the spec. Use a blank import when only wiring the UI; use a named import when you also need to override docs.SwaggerInfo at runtime:
import _ "yourmodule/docs" // blank: registers spec, no identifier
import docs "yourmodule/docs" // named: use when overriding SwaggerInfo
Wire the UI endpoint — pick your framework:
// Gin
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
// Echo
e.GET("/swagger/*", echoSwagger.WrapHandler)
// Fiber
app.Get("/swagger/*", fiberSwagger.WrapHandler(swaggerFiles.Handler))
// net/http
mux.Handle("/swagger/", httpSwagger.Handler(swaggerFiles.Handler))
// Chi
r.Get("/swagger/*", httpSwagger.Handler(swaggerFiles.Handler))
Access the UI at /swagger/index.html.
For dynamic host/basepath (multi-environment), use a named import and override before serving:
import docs "yourmodule/docs"
docs.SwaggerInfo.Host = os.Getenv("API_HOST")
docs.SwaggerInfo.BasePath = "/api/v1"
Full CLI reference
Place in main.go (or the file passed via -g). These annotations define the top-level spec:
// @title My API
// @version 1.0
// @description Short description of the API.
// @host localhost:8080
// @BasePath /api/v1
// @schemes http https
// @contact.name API Support
// @contact.email [email protected]
// @license.name Apache 2.0
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description Type "Bearer" followed by a space and the JWT token.
Annotate each handler function. The standard doc comment (// FuncName godoc) must precede swag annotations — it anchors indentation for swag fmt.
// ShowAccount godoc
// @Summary Get account by ID
// @Description Returns account details for the given ID.
// @Tags accounts
// @Accept json
// @Produce json
// @Param id path int true "Account ID"
// @Param filter query string false "Optional search filter"
// @Success 200 {object} model.Account
// @Success 204 "No content"
// @Failure 400 {object} api.ErrorResponse
// @Failure 404 {object} api.ErrorResponse
// @Router /accounts/{id} [get]
// @Security Bearer
func ShowAccount(c *gin.Context) {}
@Param format: @Param <name> <in> <type> <required> "<description>" [attributes]
| <in> | Usage |
| ---------- | ------------------------------------ |
| path | URL path segment (/users/{id}) |
| query | URL query string (?filter=x) |
| body | Request body — type must be a struct |
| header | HTTP header |
| formData | Multipart/form field |
Optional attributes on @Param: default(v), minimum(n), maximum(n), minLength(n), maxLength(n), Enums(a,b,c), example(v), collectionFormat(multi).
@Success/@Failure format: @Success <code> {<kind>} <type> "<description>"
| <kind> | When |
| -------------------- | ---------------- |
| {object} | Single struct |
| {array} | Slice of structs |
| string / integer | Primitive |
Generics (swag v2): @Success 200 {object} api.Response[model.User]
Nested composition: @Success 200 {object} api.Response{data=model.User}
Define once at the API level (in main.go), apply per endpoint with @Security.
// Bearer / JWT
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// API key in header
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name X-API-Key
// Basic auth
// @securityDefinitions.basic BasicAuth
// OAuth2 authorization code
// @securityDefinitions.oauth2.authorizationCode OAuth2
// @authorizationUrl https://example.com/oauth/authorize
// @tokenUrl https://example.com/oauth/token
// @scope.read Read access
// @scope.write Write access
Apply to an endpoint:
// @Security Bearer
// @Security OAuth2[read, write]
// @Security BasicAuth && ApiKeyAuth // AND — both required
Enrich models without changing their Go type:
type CreateUserRequest struct {
Name string `json:"name" example:"Jane Doe" minLength:"2" maxLength:"100"`
Role string `json:"role" enums:"admin,user,guest" example:"user"`
Age int `json:"age" minimum:"18" maximum:"120"`
Avatar []byte `json:"avatar" swaggertype:"string" format:"base64"`
Secret string `json:"-" swaggerignore:"true"` // excluded from docs
}
| Tag | Purpose |
| --- | --- |
| example | Example value shown in Swagger UI |
| enums | Comma-separated allowed values |
| swaggertype | Override detected type (e.g., "primitive,integer" for time.Time) |
| swaggerignore:"true" | Exclude field from the generated schema |
| extensions | Add OpenAPI extensions: extensions:"x-nullable,x-deprecated=true" |
| Mistake | Why it breaks | Fix |
| --- | --- | --- |
| Missing _ "yourmodule/docs" import | Schema not registered; UI loads empty | Add blank import in main.go or server init |
| Stale docs/ after code changes | Docs diverge from implementation; consumers get wrong schema | Re-run swag init after every annotation change |
| @Param body with primitive type | swag cannot derive schema from string; generation fails | Always use a named struct for body params |
| No @Security on protected routes | Swagger UI shows no lock icon; testers send unauthenticated requests | Apply @Security to every authenticated endpoint |
| General info annotations in the wrong file | swag silently skips them; spec has no title/host | Use -g <file> flag or move annotations to main.go |
| Using {object} with a map type | swag cannot generate a schema for map[string]any without help | Use a named struct or annotate with swaggertype |
| Multi-word @Tags without quotes | Tags split on spaces, producing malformed grouping | Quote tags with spaces: @Tags "user accounts" |
samber/cc-skills-golang@golang-security for securing the Swagger UI endpoint in production (disable or gate with auth middleware).samber/cc-skills-golang@golang-grpc for gRPC — use grpc-gateway with its own OpenAPI generator instead of swag.This skill is not exhaustive. Refer to the swaggo/swag documentation and code examples for up-to-date API signatures and usage patterns. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See samber/cc-skills-golang@golang-pkg-go-dev skill (godig) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See samber/cc-skills-golang@golang-gopls skill (gopls). Context7 remains a fallback for docs not indexed on pkg.go.dev.
If you encounter a bug or unexpected behavior in swag, open an issue at <https://github.com/swaggo/swag/issues>.
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification
Take samber/golang-swagger from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference go.
Without those the skill loads but fails at the first command.