Generating Go code from OpenAPI schemas
Turn OpenAPI schemas into clean, dependency-free Go models.Generate formatted Go models from OpenAPI schemas. The default output uses only the Go standard
library. Import github.com/pb33f/libopenapi/generator/golang.
For HTTP clients, see Generating SDKs. For interfaces and type aliases, see Generating TypeScript.
Rendering a whole component map
Save your spec as openapi.yaml. This writes its component schemas to models.gen.go:
package main
import (
"fmt"
"os"
"github.com/pb33f/libopenapi"
"github.com/pb33f/libopenapi/generator/golang"
)
func main() {
source, err := os.ReadFile("openapi.yaml")
if err != nil {
panic(err)
}
doc, err := libopenapi.NewDocument(source)
if err != nil {
panic(err)
}
model, err := doc.BuildV3Model()
if err != nil {
panic(err)
}
if model.Model.Components == nil {
panic("the document has no components")
}
file, err := golang.NewGenerator().RenderSchemas(model.Model.Components.Schemas)
if err != nil {
panic(err)
}
for _, d := range file.Diagnostics {
fmt.Printf("[%s] %s: %s\n", d.Code, d.Path, d.Message)
}
if err := os.WriteFile("models.gen.go", file.Source, 0o644); err != nil {
panic(err)
}
}
Rendering a single schema
golang.RenderSchema("Product", proxy) accepts a *base.SchemaProxy and returns source bytes.
Use RenderSchemas for a component map with references between models.
What you get back
RenderSchemas returns a *GeneratedFile with Source, PackageName, Types, and Diagnostics.
The optional SchemaMetadata sidecar supports round trips.
How OpenAPI shapes map to Go
| Schema | Go |
|---|---|
| Object with properties | Struct. |
| Array | []T. |
| String / integer / number / boolean | string / int / float64 / bool. |
| Optional property | Pointer with omitempty. |
| Nullable | Pointer. |
| Scalar enum | Named type; constants are optional. |
Unambiguous discriminated oneOf |
Typed union and JSON wrapper. |
Ambiguous oneOf / anyOf |
json.RawMessage wrapper. |
Inline objects get named types. String formats stay strings unless configured; numeric formats
such as int64 and float select sized Go types.
Shaping the output
Pass options to golang.RenderSchema or golang.NewGenerator:
| Option | Effect |
|---|---|
WithPackageName(name) |
Package name; default models. |
WithGeneratedComment(true) |
Generated-code header. |
WithEnumConstants(true) |
Typed enum constants. |
WithOptionalFieldsAsPointers(false) |
Optional fields become values. |
WithGenerateYAMLTags(true) |
YAML tags alongside JSON tags. |
WithFormatMapping(format, goType, importPath) |
Custom string-format type. |
WithTypeNameResolver(fn) |
Custom names. |
WithSchemaMetadataSidecar(true) |
Round-trip metadata. |
Diagnostics
Inspect Code, Path, and Message for lossy or notable decisions. Validation constraints such
as minimum and pattern are not enforced by generated models.
Typed unions
A discriminator or shared required const can select a concrete variant during JSON decoding.
Ambiguous compositions keep the payload as raw JSON.
Enums as constants
WithEnumConstants(true) emits a typed constant for each scalar enum value.
Round-tripping unknown fields
Schema-valued additionalProperties collects extra keys in an AdditionalProperties map.
Generated JSON methods preserve them through decode/encode. Use
WithAdditionalPropertiesMethods(false) to supply your own methods.
Going the other way
Parsing Code covers Go → OpenAPI and the metadata sidecar for faithful round trips.