Guide
Turn any OpenAPI 3.x document into a published, auto-rebuilding TypeScript SDK — without adding a single file to your API repo.
Last reviewed: April 23, 2026
Most teams who ship a backend with an OpenAPI document eventually want a TypeScript SDK to go with it. The reason is usually mundane: the frontend team is tired of hand-writing fetch wrappers, a customer asked for a typed client, or a second service showed up and started duplicating the request shapes. What they discover is that "generate a TypeScript SDK from OpenAPI" is three separate problems pretending to be one.
The first problem is generation quality. A lot of off-the-shelf generators produce code that looks generated — wide `any` on response bodies, a single AxiosError for every failure, no validation at the wire boundary, inconsistent naming. The second is the pipeline: every regeneration becomes a PR, and the SDK drifts from the spec because nobody wants to babysit the CI step. The third is publishing: the generator stops at source code, and somebody on the team has to own the npm identity, version bumps, and registry credentials.
SDK Factory treats OpenAPI → TypeScript SDK as the whole loop. You paste the URL of your OpenAPI document, pick a package name and a registry, and the first version is on npm within minutes. After that, we poll the schema, detect real changes (canonicalised hash, not whitespace), rebuild, and publish — with no PR, no Action, no human in the loop.
What you actually spend time on when you wire this by hand — and what eventually drifts.
typescript-axios gives you `AxiosResponse<any>` in too many places. typescript-fetch emits unvalidated `as T` casts. Error handling collapses into one `catch (e: any)`. You either accept that or hand-patch generated code after every regeneration — which defeats the point.
Nobody schedules re-generation until the SDK breaks. The gap between a spec change and a published SDK is measured in sprints, not minutes, because nothing automatic closes it.
CI runs the generator, opens a PR, somebody reviews the 4 000-line diff, merges, the publish step runs. That PR is pure ceremony — nothing to review that a typechecker can't — but every schema change pays it.
The generator finishes. You still need to build, version, `npm publish`, rotate tokens, and — if you're on a private registry — wire that yourself. That's usually a week of someone's time before the SDK is actually installable.
The hand-rolled version versus the pasted-URL version — same end state, very different footprint.
# Install a generator. Pick one (typescript-axios? typescript-fetch?
# typescript-node? openapi-typescript? openapi-zod-client?). Each
# produces subtly different code. Commit your choice.
npm install -D @openapitools/openapi-generator-cli
# Write a config. Decide on additional-properties flags.
cat > openapitools.json <<'JSON'
{ "generator-cli": { "version": "7.5.0" } }
JSON
# Run the generator. Get a directory of source code.
npx openapi-generator-cli generate \
-i ./openapi.yaml -g typescript-axios \
-o ./generated --additional-properties=npmName=@acme/api-client
# Build. Version. Publish. Own the failure modes.
cd generated && npm install && npm run build
npm version patch && npm publish --access public
# Now wire a cron / GitHub Action so this repeats when the schema
# changes. Review every regenerated diff in a PR. Rotate the npm
# token quarterly. Debug when the generator upgrades break output.Paste schema URL: https://api.example.com/openapi.yaml Registry: npm (public) / GitHub Packages / custom Package name: @acme/api-client ┌─────────────────────┐ │ Create & publish │ └─────────────────────┘ → First version on your registry within minutes. → Every future schema change triggers a rebuild automatically. → No files added to your API repo. No PRs. No Action to maintain.
The same pain points, handled by the pipeline — not by whoever is on call this week.
Dashboard → OpenAPI URL → package name → registry → publish. No CLI, no Action, no fern/ or .speakeasy/ directory committed to your API repo. The first tarball lands on your registry while you're still on the onboarding screen.
We poll the schema URL, canonicalise the document (sorted keys, stable refs, whitespace stripped) and SHA-256 hash it. Same hash = nothing ships. Different hash = a fresh build kicks off within minutes and publishes a new version.
ESM + CJS + a single bundled `.d.ts` per entry. Zod schemas validate both sides of the wire. Errors are a discriminated union per operation, not a generic AxiosError. Retries, timeouts, and interceptors are first-class — not additional-properties flags.
The exact artifact that was published is stored in S3, keyed by deployment ID, with the schema hash that produced it. If a downstream consumer asks "what changed between 1.4.2 and 1.4.3?", the answer is two clicks away.
A TypeScript SDK is more than types wrapped around fetch. The output has to compile under strict mode across ESM and CJS consumers, ship a single bundled `.d.ts` per entry so editors don't resolve 300 files on autocomplete, and not ship source maps that leak internal comments.
Beyond the packaging, the runtime matters. Request bodies should be Zod-validated before they hit the wire — because the server will reject them anyway, and surfacing the error in your type-safe Zod error is far more useful than reading a 400 response body. Response bodies should be Zod-validated on the way in — because the server can drift from the spec, and you'd rather have a structured `ZodError` at the SDK boundary than an `as T` cast that silently returns an object missing half its fields.
Errors should be discriminated unions per operation. If the OpenAPI document says `createUser` can return `409 EmailTaken | 422 ValidationError | 500`, the SDK's `catch` block should narrow to that union — not to a generic error class that forces a runtime `instanceof` tree.
We poll the OpenAPI URL on a short cycle. Each fetch is canonicalised — keys sorted, `$ref`s stabilised, whitespace stripped — then SHA-256 hashed. Identical hash means nothing shipped; a different hash kicks off a build.
The canonicalisation is the load-bearing part. It means a developer who re-saves the YAML through a formatter, or a toolchain that emits keys in a different order, does not trigger a spurious SDK release. Only real content changes do.
Versioning follows `openapi.info.version` — so you control when a major bump ships. We don't guess a semver diff from the schema. If your spec says 1.4.3, the npm package is 1.4.3.
Yes. Both major versions are supported. We canonicalise the document before hashing it, so minor toolchain differences (key ordering, `$ref` styles) don't cause spurious rebuilds.
The schema URL just needs to be reachable from SDK Factory. If your spec is behind authentication, point us at an authenticated endpoint with a token we can store — token storage is AES256-encrypted and rotatable. If you need a fully air-gapped setup, that's not what we do today; OpenAPI Generator self-hosted is the honest answer for that constraint.
A built ESM bundle, a CJS bundle for older tooling, and a single bundled `.d.ts` per entry. No source, no source maps. The Zod schemas are emitted as runtime code (not just types) so validation actually happens at install-time and at call-time.
Not today — the output is opinionated on purpose (one good shape for everyone, rather than fifty flags). If you need deep output customisation, OpenAPI Generator is a better match for that workload; we'd rather ship one great default than a matrix of lukewarm ones.
On the Pro tier, a rollback is one click — we re-upload the previously published tarball from S3 and flip the registry's `latest` dist-tag. No rebuild, no version drift. On lower tiers, you can pin to the previous version on the consumer side until the next spec change ships a fix.
OpenAPI to npm package
Go from an OpenAPI URL to a versioned npm package on your registry — public, private, or custom — every time the schema changes.
OpenAPI to Zod-validated client
An OpenAPI-generated TypeScript client with Zod schemas validating every request and response at the runtime boundary.
OpenAPI to GitHub Packages
Publish a TypeScript SDK from your OpenAPI document to GitHub Packages, re-published automatically every time the schema changes.
OpenAPI to private npm registry
Publish your TypeScript SDK to a private npm registry — Verdaccio, JFrog Artifactory, Sonatype Nexus, AWS CodeArtifact, Cloudsmith — without writing the glue yourself.
One app on the Free tier, no card required. Paste your OpenAPI URL and see the generated TypeScript SDK in minutes.