# gin-swagger: Swagger 2.0 docs from Go comments, served at /swagger

> gin-swagger is swaggo's MIT-licensed Gin middleware that automatically generates RESTful API documentation with Swagger 2.0, pairing the swag CLI's comment parser with an embedded Swagger UI handler. Comments annotate handlers with a declarative format, swag init produces a docs package with JSON and YAML, nested projects configure generation flags, and options tune the UI from expansion depth to persisted authorization.

**swaggo/gin-swagger** — gin middleware to automatically generate RESTful API documentation with Swagger 2.0.

- Repository: https://github.com/swaggo/gin-swagger
- Stars: 4,239 · Forks: 297
- Language: Go
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/swaggo-gin-swagger

## Two tools, one pipeline

gin-swagger is gin middleware to automatically generate RESTful API documentation with Swagger 2.0, and the automatic is really a two-tool pipeline. The swag CLI parses Go comments written in a declarative comments format and generates the documentation files, a docs folder with docs.go, swagger.json and swagger.yaml. The middleware then serves those files through an embedded Swagger UI at the swagger path, importing the swaggo gin-swagger package and the swaggo files package for the embedded assets. The split keeps responsibilities clean, the parser knows the comment format, the middleware knows Gin's handler wrapping, and the generated docs package is ordinary Go code compiled into the application, so the documentation version is the binary's version. The repository history is visible in its release tags, v1.5.3 in 2022, v1.6.0 in 2023 and v1.6.1 on 2025-09-02, a pace matching the middleware layer rather than the parser it wraps, since most development energy lands upstream in swag.

## The toolchain, installed

The getting started sequence installs the CLI first:

```sh
go install github.com/swaggo/swag/cmd/swag@latest
```

with the older go get form shown and its deprecation noted, starting in Go 1.17, installing executables with go get is deprecated. Then swag init runs at the Go project root, parsing comments and generating the required files into the project's docs folder. The middleware arrives through:

```sh
go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files
```

and the two imports, gin-swagger for the middleware and swaggo files for the swagger embed files, complete the wiring. The go.mod shows the current foundations, Gin at 1.9.1, swag at 1.8.12, and the module targeting go 1.24. Keeping the docs package importable rather than emitting a standalone file is the design decision that makes CI checks possible, a build step that imports the package compiles the documentation into the same artifact as the handlers it describes, so a stale docs folder fails visibly rather than silently drifting.

## The canonical example, annotated

The canonical example starts with an ordinary handler, a Helloworld function returning a JSON string, then adds the annotation block:

```go
// @BasePath /api/v1

// PingExample godoc
// @Summary ping example
// @Schemes
// @Description do ping
// @Tags example
// @Accept json
// @Produce json
// @Success 200 {string} Helloworld
// @Router /example/helloworld [get]
func Helloworld(g *gin.Context)  {
	g.JSON(http.StatusOK,"helloworld")
}
```

Each line maps to a Swagger field, summary, description, tags, accepted and produced content types, the success response with its type, and the route with its method, plus a base path that scopes all relative routes. After swag init, the generated docs package is imported, docs.SwaggerInfo.BasePath is set in main, and the browser shows the Swagger UI at localhost:8080/swagger/index.html. The full example's main function registers the handler inside a v1 group matching the base path, the annotation and the routing agreeing by construction. The BasePath annotation deserves emphasis because it answers the mismatch every router creates, handlers registered under a versioned group are reachable at different URLs than their function names suggest, and the annotation lets the generated document reflect the public paths while the code keeps its internal structure.

## Nested projects, and the flags that reach them

Real projects rarely keep main.go at the root, and the nested directory example shows the layout, cmd/ginsimple/main.go, internal handlers and models, with the docs folder at the top. Generation takes two flags:

```bash
swag init -g ./cmd/ginsimple/main.go -o cmd/docs
```

with -g naming the entry file to parse and -o setting the output path for the generated files. The demo project tree confirms the flat case's output, docs.go, swagger.json and swagger.yaml beside go.mod and main.go, and the nested tree shows the same outputs under cmd/docs. A multiple APIs feature introduced in swag v1.7.9 extends the story to services exposing several documents, the feature the configuration table's InstanceName option completes. The flat and nested trees also show where the generated files should live relative to imports, the docs import path in the example follows the module path, so relocating output with -o means adjusting the import accordingly, and the generated docs.go carries the JSON and YAML as embedded strings served by the middleware.

## UI configuration, option by option

The middleware's WrapHandler accepts configuration options, and the table runs from cosmetic to behavioral. URL points at the API definition, defaulting to doc.json. DocExpansion controls initial expansion as list, full or none, with list expanding only tags. DeepLinking enables deep links to tags and operations, defaulting true. DefaultModelsExpandDepth and DefaultModelExpandDepth control model expansion, with negative one completely hiding the models, the setting the configuration example passes explicitly. DefaultModelRendering chooses example or model as the first view. InstanceName names the document for multiple instances on one router, each requiring a unique name and matching the instanceName parameter to swag init. PersistAuthorization defaults to false, the option that keeps authorization data across page reloads when enabled. The PersistAuthorization option matters most in practice for teams using the UI interactively, since re-entering tokens on every page reload is the friction that pushes developers away from live documentation, and the default stays false for deployments where persistence is unwanted.

## The example directory, and testing the middleware

The repository keeps three example projects, basic, gzipped and multiple, the gzipped one pulling in gin-contrib/gzip, which appears in the module's direct dependencies, so compressed responses and the Swagger UI are a documented combination. A swagger_test.go sits beside swagger.go at the repository root, testing the middleware itself, and the module carries a goreleaser configuration for release packaging. The small repository footprint, one source file, one test file and examples, reflects the middleware's scope, all the heavy lifting lives in the swag project, and gin-swagger is the adapter that makes its output appear inside a Gin router. The gzip example also demonstrates the wrapping order concern, middleware that transforms responses must be configured so the documentation route still serves correct content, and the project shipping a dedicated example for the combination signals that the question comes up enough to answer in code.

## Conclusion

Use gin-swagger when a Gin service needs browsable API documentation that cannot drift from the code, since handlers are annotated in place and regeneration is one swag init command, with the docs package compiled into the binary so the UI ships with the service. Prefer hand-written OpenAPI documents when the spec should lead design rather than follow implementation. Before adopting, remember the two-part install, the swag CLI and the middleware with its files package, use the -g and -o flags for nested project layouts, and set each swagger instance's InstanceName when multiple documents share one router.

## FAQ

### What is gin-swagger?

gin-swagger is an MIT-licensed Gin middleware that automatically generates RESTful API documentation with Swagger 2.0. Handlers are annotated with declarative comments, the swag CLI generates a docs package with swagger.json and swagger.yaml, and the middleware serves an embedded Swagger UI at the swagger path of the Gin router.

### How do you generate Swagger docs for a Gin project?

Install the swag CLI with go install github.com/swaggo/swag/cmd/swag@latest, annotate handlers with the comment format, run swag init at the project root, import the generated docs package, and register the gin-swagger middleware. For nested layouts, pass -g with the main file path and -o with the output directory.

### Can gin-swagger serve multiple Swagger documents?

Yes, through the multiple APIs feature introduced in swag v1.7.9 combined with the InstanceName configuration option, which gives each swagger instance on one gin router a unique document name, matching the instanceName parameter used when generating with swag init.

## Sources

- [Issues](https://github.com/swaggo/gin-swagger/issues)
- [License: MIT](https://github.com/swaggo/gin-swagger/blob/master/LICENSE)
- [README](https://github.com/swaggo/gin-swagger/blob/master/README.md)
- [Releases](https://github.com/swaggo/gin-swagger/releases)
- [swaggo/gin-swagger on GitHub](https://github.com/swaggo/gin-swagger)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/swaggo-gin-swagger
