This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
# Run all tests
go test ./...
# Run a single test
go test -run TestHandler/Docs/SwaggerUI ./...
# Run tests with coverage
go test -coverprofile=coverage.out ./...
# Lint (requires golangci-lint)
golangci-lint run
# Tidy dependencies
go mod tidyspec-ui is a Go library that serves OpenAPI documentation UIs as HTTP handlers. It supports five UI providers: SwaggerUI, StoplightElements, ReDoc, Scalar, and RapiDoc. Each provider comes in two variants: CDN mode and embedded mode.
- The user calls
specui.NewHandler(opts...)with functional options fromoption.goand a provider-specificWithUI()option - Options populate a
config.SpecUIstruct (defined inconfig/config.go) Handler.Docs()callscfg.DocsHandlerFactory— set by the provider'sWithUI()— to create the handler once (viasync.Once)Handler.Assets()callscfg.AssetsHandlerFactoryfor embedded asset serving; returnsnilin CDN modeHandler.Spec()dispatches tointernal/spec, which serves the raw OpenAPI file
Each provider lives in two top-level packages:
<provider>/(e.g.,swaggerui/,rapidoc/): CDN mode — loads JS/CSS from pinned CDN URLs ininternal/constant/constant.go. Containshandler.go,index.tpl.go, andoption.go.<provider>emb/(e.g.,swaggeruiemb/,rapidocemb/): Embedded mode — setscfg.EmbedAssets = trueand delegates to the CDN handler, but also registersAssetsHandlerFactoryto serve files from the package'sassets/directory via//go:embed assets.
Each provider package exposes WithUI(cfg ...config.<Provider>) specui.Option. Only the imported provider's code is linked into the binary (tree-shaking via factory pattern).
-
option.go(root): Shared options only —WithTitle,WithDocsPath,WithSpecPath,WithAssetsPath,WithSpecFile,WithSpecEmbedFS,WithSpecIOFS,WithSpecGenerator,WithCacheAge. Provider selection is done by importing the provider package. -
config/config.go: A singleSpecUIstruct holds all configuration.DocsHandlerFactoryandAssetsHandlerFactoryare function fields set byWithUI(). Each provider has its own typed config struct with enum-like constants (e.g.,SwaggerLayout,RapiDocTheme). -
internal/spec/spec.go: Usessync.Onceto read the spec file once and cache it. Supports four source modes:SpecGeneratorinterface,embed.FS,fs.FS, or plain OS file path. -
handler.go:Docs(),Spec(),Assets()— the three HTTP handlers. Callhandler.AssetsEnabled()to check if embedded mode is active; if so, registerhandler.Assets()athandler.AssetsPath() + "/".
- Add a new
Providerconstant toconfig/config.go - Add the provider config struct to
config/config.go - Create
<provider>/handler.go,<provider>/index.tpl.go,<provider>/option.go—option.gosetsDocsHandlerFactory,AssetsHandlerFactory = nil, and any config defaults - Add CDN asset URLs to
internal/constant/constant.go - Create
<provider>emb/handler.go,<provider>emb/assets.go,<provider>emb/option.go—assets.gouses//go:embed assetsand serves files;option.gosetsEmbedAssets = trueand registers both factories