swaggo/swag
Automatically generate RESTful API documentation with Swagger 2.0 for Go.
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 1w ago
- ✓57+ active contributors
- ✓Distributed ownership (top contributor 22% of recent commits)
Show all 6 evidence items →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/swaggo/swag)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/swaggo/swag on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: swaggo/swag
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/swaggo/swag shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 1w ago
- 57+ active contributors
- Distributed ownership (top contributor 22% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live swaggo/swag
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/swaggo/swag.
What it runs against: a local clone of swaggo/swag — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in swaggo/swag | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 38 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of swaggo/swag. If you don't
# have one yet, run these first:
#
# git clone https://github.com/swaggo/swag.git
# cd swag
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of swaggo/swag and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "swaggo/swag(\\.git)?\\b" \\
&& ok "origin remote is swaggo/swag" \\
|| miss "origin remote is not swaggo/swag (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "cmd/swag/main.go" \\
&& ok "cmd/swag/main.go" \\
|| miss "missing critical file: cmd/swag/main.go"
test -f "gen/gen.go" \\
&& ok "gen/gen.go" \\
|| miss "missing critical file: gen/gen.go"
test -f "field_parser.go" \\
&& ok "field_parser.go" \\
|| miss "missing critical file: field_parser.go"
test -f "formatter.go" \\
&& ok "formatter.go" \\
|| miss "missing critical file: formatter.go"
test -f "doc.go" \\
&& ok "doc.go" \\
|| miss "missing critical file: doc.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 38 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~8d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/swaggo/swag"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
swag is a Go code generation tool that parses specially-formatted comments in Go source files (e.g., // @Summary, // @Router) and automatically generates Swagger 2.0 (OpenAPI v2) specification files and interactive API documentation. It bridges the gap between Go handler code and OpenAPI docs by reading annotations in controllers and models, eliminating manual YAML maintenance for REST APIs. Single package design with cmd/swag as the CLI entry point (cmd/swag/main.go). Core parsing logic lives in root .go files (const.go, enums.go, doc.go, etc.). Example projects in example/basic and example/celler demonstrate real-world usage with Gin. Generated docs go into docs/ folders within each project (example/{basic,celler}/docs/). Makefile orchestrates builds and tests.
👥Who it's for
Go backend developers building REST APIs with frameworks like Gin, Echo, or chi who want to expose self-documenting Swagger UI without writing and maintaining separate API specifications manually.
🌱Maturity & risk
Production-ready and actively maintained. The codebase is substantial (~605k Go lines), has comprehensive CI/CD via GitHub Actions (ci.yml, docker.yml), includes two full example applications (basic, celler), and shows continued development. No signs of abandonment, though commit recency data is not visible in provided metadata.
Low risk for core functionality. Dependencies are well-established (go-openapi/*, Gin, PuerkitoBio packages). Single-author maintainer model (swaggo org) could create bottleneck if unmaintained, but GitHub Actions and issue templates suggest active governance. Breaking changes are possible with major version bumps in Swagger spec support, so pin versions in go.mod.
Active areas of work
Not explicitly visible from file listing, but the codebase structure suggests ongoing maintenance: two complete example apps (basic, celler with 605 files), recent dependency updates (Go 1.24.0 in celler/go.mod), active GitHub workflows for CI and Docker builds. Presence of PULL_REQUEST_TEMPLATE.md and CODE_OF_CONDUCT.md indicates active contribution process.
🚀Get running
git clone https://github.com/swaggo/swag.git
cd swag
go mod download
go build -o bin/swag ./cmd/swag/main.go
./bin/swag init --help
Daily commands:
Development: go run ./cmd/swag/main.go init (initializes docs in current project). Testing: make test (inferred from Makefile). For examples: cd example/celler && go run main.go (starts a sample API server with embedded Swagger UI). Build: go build -o swag ./cmd/swag/main.go.
🗺️Map of the codebase
cmd/swag/main.go— Entry point for the swag CLI tool that orchestrates documentation generation from Go source code annotationsgen/gen.go— Core generator logic that parses Go code, extracts API metadata, and produces Swagger/OpenAPI specificationsfield_parser.go— Parses struct fields and type information to extract API parameter and response schema definitionsformatter.go— Formats and validates generated Swagger documentation output into compliant JSON/YAML specsdoc.go— Handles parsing of swagger doc comments and annotations from Go source filesenums.go— Defines enumeration types and constants used throughout the code generation pipelinego.mod— Module definition and core dependencies including go-openapi packages for Swagger spec generation
🧩Components & responsibilities
- AST Parser (field_parser.go, doc.go) (Go AST, regexp for comment parsing) — Extracts API metadata from Go source code comments and type definitions
- Failure mode: Malformed annotations or unsupported types cause parse errors; no documentation generated
- Generator (gen/gen.go) (go-openapi/spec) — Orchestrates building Swagger spec from parsed Go constructs
- Failure mode: Type resolution failures or circular dependencies crash generation
- Formatter (formatter.go, format/format.go) (go-openapi/validate, standard library json/yaml) — Validates and formats final Swagger spec into YAML/JSON output
- Failure mode: Invalid specs fail validation; malformed output prevents consumption
- CLI (cmd/swag/main.go) (flag package, os/exec) — Entry point accepting user input and coordinating build pipeline
- Failure mode: Missing or invalid flags cause early exit without documentation
- Type System (enums.go, const.go) (Go constants and type definitions) — Defines canonical enumeration values for HTTP methods, parameter locations, Swagger keywords
- Failure mode: Typos in enum values produce invalid Swagger specs
🔀Data flow
Go source files (.go)→AST Parser— Developer writes handlers with swagger: annotations; swag reads and parses filesAST Parser→Generator— Extracted annotations and type definitions passed to generator for spec constructionGenerator→Formatter— Built Swagger spec JSON passed to formatter for validation and serializationFormatter→swagger.yaml / docs.go— Formatted spec written to disk as YAML and embedded in Go filedocs.go→gin-swagger middleware— Generated docs.go imported at runtime to serve Swagger UI endpointsundefined→undefined— undefined
🛠️How to make changes
Add a New API Endpoint with Swagger Documentation
- Create handler function with swagger annotations in comments following the format: // @Summary, // @Description, // @Param, // @Success (
example/celler/controller/bottles.go) - Add route definition in main.go that registers the handler (
example/celler/main.go) - Run 'swag init' to trigger code generation which parses annotations and updates docs/swagger.yaml (
cmd/swag/main.go) - Generated swagger.yaml is automatically imported by gin-swagger middleware to serve at /swagger/* (
example/celler/docs/docs.go)
Support a New Type in Schema Generation
- Add type mapping logic in field_parser.go to handle the new Go type (
field_parser.go) - Define corresponding Swagger schema type in enums.go if needed (
enums.go) - Add test case demonstrating the type parsing in field_parser_test.go (
field_parser_test.go) - Update example with model using the new type and run swag init to verify output (
example/object-map-example/controller/response.go)
Extend Documentation Generation for New Annotation Tags
- Define the new swagger annotation enum value in enums.go (e.g., @Deprecation, @Security) (
enums.go) - Implement parsing logic in doc.go to extract and process the new annotation (
doc.go) - Update gen.go to incorporate the parsed annotation into the final Swagger spec structure (
gen/gen.go) - Add integration test in gen_test.go verifying the annotation is correctly included in output (
gen/gen_test.go)
🔧Why these technologies
- Go AST (Abstract Syntax Tree) — Native Go standard library support for parsing Go source code with full type information and comment extraction
- go-openapi libraries (spec, loads, validate) — Authoritative Swagger 2.0 schema generation and validation to ensure OpenAPI compliance
- Gin-Gonic (examples only) — Popular Go web framework for demonstrating real-world integration patterns
- Go modules — Dependency management and versioning for reproducible builds
⚖️Trade-offs already made
-
Swagger 2.0 instead of OpenAPI 3.0
- Why: Swagger 2.0 is simpler and backward-compatible; more stable ecosystem at time of design
- Consequence: Cannot represent some advanced OpenAPI 3.0 features (webhooks, discriminators); future migration needed
-
Comment-based annotations instead of struct tags
- Why: Allows rich, multi-line documentation without cluttering struct definitions
- Consequence: Annotations must be kept in sync manually; easier to get out of date than codegen from tags
-
Recursive type resolution on every generation
- Why: Ensures up-to-date schemas reflecting current code; no stale cache issues
- Consequence: Higher latency for projects with large type hierarchies; cannot leverage incremental builds
🚫Non-goals (don't propose these)
- Does not support OpenAPI 3.0+ specifications (Swagger 2.0 only)
- Does not automatically enforce API versioning or schema evolution
- Does not generate client SDKs or server stubs (documentation only)
- Does not validate runtime request/response conformance (static analysis only)
- Does not manage authentication/authorization definitions beyond documentation
🪤Traps & gotchas
- Annotation parsing is whitespace-sensitive: swag comments must follow exact format (e.g.,
// @Summary Description, not//@Summary). 2. Generated docs overwrite: runningswag initregenerates the docs/ folder; do not hand-edit generated files (docs.go, swagger.yaml). 3. Go version constraint: project requires Go 1.24+ (from celler/go.mod); older projects may have compatibility issues. 4. Type resolution requires imports: swag walks Go source files to resolve struct types; types must be importable in the same module or explicitly imported in handler files. 5. No hot reload in dev: generated docs require re-runningswag initorswag fmt; no file watcher by default.
🏗️Architecture
💡Concepts to learn
- Go AST (Abstract Syntax Tree) Walking — swag parses Go source files by walking the AST to extract type definitions, function signatures, and comment annotations; understanding Go's ast package is essential to contributing to the parser.
- Swagger 2.0 / OpenAPI v2 Specification — swag generates Swagger 2.0 specs (not OpenAPI 3.0); knowing the Swagger spec structure (paths, operations, parameters, schemas) is critical to adding new annotation support.
- Annotation-Driven Code Generation — swag's core pattern of reading special comments as directives differs from traditional code generators; this design choice enables doc-as-code alongside handler logic.
- Reflection and Type Resolution in Go — swag must resolve custom struct types and handle generics; it uses Go's reflect package to introspect types and map them to JSON Schema objects in the Swagger spec.
- YAML Serialization / go-yaml — Generated swagger.yaml files are YAML; swag serializes Swagger specs to both YAML and JSON formats, requiring careful handling of struct tags and encoding.
- JSON Schema — Swagger specs use JSON Schema to describe request/response bodies; swag must convert Go struct definitions into valid JSON Schema representations (properties, types, required fields).
- HTTP Method and Content-Type Semantics — Correctly mapping Go handlers to Swagger operations requires understanding REST conventions (GET vs POST, multipart/form-data vs application/json); swag's annotation parsing enforces these rules.
🔗Related repos
swaggo/gin-swagger— Official Gin middleware for serving generated Swagger UI; users of swag almost always pair it with gin-swagger for handler routing.swaggo/files— Embedded Swagger UI and ReDoc assets; required as a dependency to serve UI in generated code.getkin/kin-openapi— Alternative Go OpenAPI parser/builder; similar problem domain but different API and focuses more on validation than code generation.go-swagger/go-swagger— Competing Go Swagger code generator; generates Go server stubs from existing Swagger specs (opposite direction from swag).deepmap/oapi-codegen— Another Go code generator from OpenAPI specs; more modern (supports OAS 3.0) but requires separate spec file unlike swag's annotation-driven approach.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for enums.go type parsing and validation
The enums.go file exists but enums_test.go is minimal. Given that swag automatically generates Swagger documentation, proper enum handling is critical for API schema correctness. Adding tests for enum type detection, custom type parsing, and edge cases would prevent regressions in a core feature.
- [ ] Review enums.go to identify all enum parsing logic and type detection functions
- [ ] Expand enums_test.go with tests for: basic enum types, custom types, string/int/uint variants, and edge cases like empty enums
- [ ] Add integration tests in example/celler or example/basic to verify enums render correctly in generated swagger.yaml
- [ ] Ensure test coverage reaches >85% for enums.go
Add Go 1.24 compatibility and version-specific CI workflow
The go.mod in example/celler specifies go 1.24.0, but the repo likely tests against multiple Go versions. The .github/workflows/ci.yml should explicitly test against Go 1.21, 1.22, 1.23, and 1.24 to catch version-specific issues early and document minimum supported version.
- [ ] Review .github/workflows/ci.yml to identify current Go version test matrix
- [ ] Add a matrix strategy testing Go 1.21+ and specifically 1.24.0 to catch compatibility issues
- [ ] Update README.md to explicitly state minimum Go version supported
- [ ] Test cmd/swag/main.go and core parsing logic against each version
Add integration tests for go.mod/go.sum module support with real examples
The file structure shows example/go-module-support exists, but there's no visible test coverage validating that swag correctly parses dependencies across modules. Add tests to verify swag handles vendored deps, local module replacements, and indirect dependencies correctly when generating docs.
- [ ] Create tests in example/go-module-support validating swag parses models from imported modules
- [ ] Add a .github/workflows test job that runs 'swag init' in example/go-module-support and verifies swagger.json/yaml contain expected external type definitions
- [ ] Test edge cases: circular module dependencies, version mismatches, and replaced modules (go.mod replace directive)
- [ ] Document expected behavior in CONTRIBUTING.md
🌿Good first issues
- Add test coverage for edge cases in enum parsing (enums.go has no corresponding enums_test.go with comprehensive coverage of all HTTP method and param type combinations).
- Implement support for OpenAPI 3.0 spec generation alongside Swagger 2.0 (const.go and doc.go hardcode v2 logic; a feature branch could add v3 emitter).
- Create a GitHub Actions workflow that automatically generates and commits updated swagger.yaml files on pull requests (example/celler/.../swagger.yaml is checked in but not auto-updated in CI).
⭐Top contributors
Click to expand
Top contributors
- @dependabot[bot] — 22 commits
- @sdghchj — 7 commits
- @okhowang — 6 commits
- @ubogdan — 5 commits
- @KristofferFJ — 3 commits
📝Recent commits
Click to expand
Recent commits
fa1d2c8— fix: deduplicate required fields when parent struct shadows embedded struct field (#2159) (chiptus)652e82c— feat: support query and param struct tags for Echo framework compatibility (#2154) (maxclaus)b80ab25— feat: enhance swagger specification with comprehensive schemas and examples (#2146) (localai-bot)ed32573— feat: allow @ character in router path (#2124) (mykold)233aa91— bugfix: parse generic parameterized enum constants (#2118) (abdivasiyev)c093962— support form:"-" tag to skip struct fields in params (#2130) (nohy6630)1c69c06— fix: Honor @name annotations for recursive types (#2032) (pborgen)0a750ad— refactor: replace interface{} with any (#2110) (shindonghwi)ea750e7— chore(deps): bump golang.org/x/crypto in /example/go-module-support (#2113) (dependabot[bot])5bd3308— chore(deps): bump golang.org/x/crypto in /example/celler (#2099) (dependabot[bot])
🔒Security observations
Failed to generate security analysis.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.