Open-source OpenAPI SDK generator written in Zig. Parses an OpenAPI 3.1 spec and generates typed HTTP client SDKs in TypeScript, Rust, Python, and Go.
Built as an alternative to Stainless.
flowchart TD
spec["📄 OpenAPI Spec\n(.json / .yaml)"]
spec --> sdks
subgraph sdks["Generated SDKs"]
direction LR
ts["🟦 TypeScript"]
rs["🦀 Rust"]
py["🐍 Python"]
go["🐹 Go"]
zig["⚡ Zig"]
java["☕ Java"]
kt["🟣 Kotlin"]
cs["🟩 C#"]
swift["🍎 Swift"]
dart["🎯 Dart"]
rb["💎 Ruby"]
php["🐘 PHP"]
scala["🔴 Scala"]
end
# Build (requires Zig 0.15.2+)
zig build
# Generate SDKs from an OpenAPI spec
./zig-out/bin/sterling generate \
--spec openapi.json \
--config sterling.toml
# With LLM enhancement (optional)
ANTHROPIC_API_KEY=sk-... ./zig-out/bin/sterling generate \
--spec openapi.json \
--config sterling.toml \
--enhance# sterling.toml
[project]
name = "chelsea"
version = "0.1.0"
[[targets]]
language = "typescript"
output_dir = "./generated/typescript"
[[targets]]
language = "rust"
output_dir = "./generated/rust"
[[targets]]
language = "python"
output_dir = "./generated/python"
[[targets]]
language = "go"
output_dir = "./generated/go"
[llm]
provider = "anthropic"
api_key = "${ANTHROPIC_API_KEY}"
model = "claude-sonnet-4-20250514"From Chelsea's Orchestrator Control Plane API (43 schemas, 35 paths, 48 operations):
| Language | Files | Features |
|---|---|---|
| TypeScript | client.ts, models.ts, index.ts, package.json, tsconfig.json | fetch-based, typed request/response bodies |
| Rust | client.rs, models.rs, lib.rs, Cargo.toml | reqwest + serde, typed structs and enums |
| Python | client.py, models.py, __init__.py, pyproject.toml | httpx, dataclasses, async/await |
| Go | client.go, models.go, go.mod | net/http, typed structs with json tags |
All SDKs include:
- Typed models from
components/schemas(structs, enums, nested refs) - Typed request/response bodies from
$refresolution - Path parameter interpolation (e.g.
vm_idas function argument) - Bearer token authentication
- Generated README with usage examples
With --enhance, Sterling validates each generated SDK immediately after generation by running the target language's build toolchain. The LLM is only invoked if a build error is detected — it is not used to post-process every file by default.
When build errors are found, the failing source files are sent to Claude along with the compiler error output as context. Claude fixes the errors and the SDK is re-validated. If the API call fails or the build still doesn't pass, the pre-enhancement output is preserved.
This keeps token usage proportional to actual problems rather than burning tokens on code that already compiles cleanly.
src/
main.zig CLI: generate, init, version
parser/openapi.zig OpenAPI 3.1 JSON parser (schemas, operations, $refs)
config/config.zig TOML config loader
config/toml.zig TOML parser
generator/
sdk.zig Core generator (iterates targets, renders templates)
template.zig Mustache-like engine ({{var}}, {{#each}}, {{#if}})
llm/enhancer.zig Optional LLM post-processing via Anthropic API
templates/
typescript/ 6 templates (client, models, index, package.json, ...)
rust/ 4 templates (client, models, lib, Cargo.toml)
python/ 5 templates (client, models, __init__, pyproject, ...)
go/ 4 templates (client, models, go.mod, README)
zig/ 3 templates (client, build.zig, README)
Sterling is configured to auto-generate SDKs from hdresearch/chelsea's OpenAPI spec:
# Generate from Chelsea's orchestrator spec (the public API)
./zig-out/bin/sterling generate \
--spec ../chelsea/openapi/orchestrator.openapi.json \
--config sterling.tomlThe GitHub Actions workflow (.github/workflows/sterling-automation.yml) runs on:
repository_dispatchfrom Chelsea when the spec changes- Daily schedule (6am UTC)
- Manual
workflow_dispatch
It generates SDKs and pushes to per-language repos (vers-sdk-ts, vers-sdk-rust,
vers-sdk-python, vers-sdk-go).
Note: vers-docs OpenAPI sync is handled by Chelsea's own sync-openapi-to-docs.yaml
workflow — Sterling does not duplicate that.
Thanks to @cartazio for identifying ambiguities in HTTP error response handling that motivated the Content-Type sniffing, error message extraction, and boolean query parameter fixes across all nine language templates.
MIT