Forge production-ready typed client SDKs from OpenAPI 3.x specs.
One language-neutral IR. Emitters for TypeScript, Go, Rust, and WASM.
Most OpenAPI generators leave teams building runtime infrastructure by hand. SpecForge delivers a complete, production-ready SDK — not just types.
| Problem with other generators | SpecForge's answer |
|---|---|
| Incomplete types — nullable, oneOf, allOf produce broken or any-typed output | Full composition: allOf merging, oneOf type guards, discriminator mapping, nullable propagation |
| No runtime — you get types but no client, auth, retry, or error handling | Production-ready runtime: auth providers, exponential backoff, pagination, middleware, idempotency, SSE streaming |
| Single language — each generator is a silo with different behavior | One IR, four targets: TypeScript, Go, Rust, and WASM plugins share the same resolved spec |
| No validation — generated code trusts the server blindly | Runtime request/response validation catches contract violations in dev and tests |
| No testing — you write mock servers by hand | specforge test generates mock server tests from example responses |
| No documentation — separate tools for API docs | specforge docs generates a static HTML documentation site |
| No CI integration — manual diffing and linting | specforge diff detects breaking changes, specforge check lints specs, GitHub Action for one-line CI |
Parse once, emit many. A language-neutral IR decouples parsing from code generation.
Handles real-world OpenAPI specs at scale — GitHub (~965 schemas / 1209 ops) and Stripe (~1431 / 587).
Handles both spec versions transparently. 3.1 type arrays, $ref siblings, and numeric exclusiveMinimum are auto-converted for parsing.
Named types stay named — no exponential inlining blow-ups. Self-referential and mutual $ref cycles are safe by construction.
allOf merges properties (last-wins, required union). oneOf/anyOf generate type guards. Discriminator mapping preserved.
allOf with one $ref: Go emits embedded structs, Rust emits #[serde(flatten)]. Proper composition, not flat merging.
IndexMap preserves spec order. Same spec + same version = identical output. Bit-stable for caching and diffing.
8 configurable rules (duplicate operation IDs, missing descriptions, unused schemas) with .specforge.yaml config.
specforge diff compares two specs: removed operations, new required parameters, type changes. Exit code 1 for CI gates.
Every generated SDK is a complete, production-ready client — not just types. All capabilities available in TypeScript, Go, and Rust.
Each generated SDK is a standalone project — no shared runtime dependency, no version coupling.
Dual ESM/CJS package, native fetch — zero runtime dependencies. Discriminated union error types, isX()/narrowX() type guards for oneOf, per-model validate functions.
Stdlib only (net/http, encoding/json) — zero third-party dependencies. Embedded structs for allOf, New{Union} helpers for discriminated oneOf deserialization.
reqwest + serde + tokio async. #[serde(flatten)] for allOf, discriminant() for oneOf, SseStream for SSE parsing over bytes_stream().
Build custom emitters in any language. Plugin SDK provides Plugin trait and export_plugin! macro. Compile to wasm32-wasi and run with specforge.
One binary, eight commands. Cross-compiled for Linux, macOS, and Windows.
Build the CLI and generate your first SDK in under 2 minutes.