Developer tool · v0.1.0 on npm

steadysdk

Built for the hundredth regeneration.

Most OpenAPI generators rewrite everything on each run, deleting custom code and renaming methods when the spec shifts. steadysdk turns an OpenAPI 3.0/3.1 spec into a dependency-free, fully typed TypeScript client and keeps it maintainable as the API evolves.

Platform
OpenAPI → TypeScript SDK generator · CLI and GitHub Action
What we did
CLI and code generator · GitHub Action · Test suite on real APIs
Stack
TypeScript · Node.js · Vitest · GitHub Actions

Walkthrough

Pick a step, or let it play. Hover or focus pauses it.

$
✔ Loaded Swagger Petstore 1.0.0 (OpenAPI 3.0.3): 11 operations, 8 schemas
+ sdk/generated/runtime.ts
+ sdk/generated/models.ts
+ sdk/generated/api/pets.ts
+ sdk/generated/api/store.ts
+ sdk/generated/api/users.ts
+ sdk/generated/client.ts
+ sdk/generated/index.ts
+ sdk/client.ts
+ sdk/index.ts
9 created
✔ SDK written to sdk (81 ms)

Why it exists

Most OpenAPI generators are “generate once and forget”: re-running them overwrites everything, wipes out hand-written helpers, and silently renames methods when the spec shifts. steadysdk is built for the second, tenth and hundredth generation.

A typical OpenAPI generator compared with steadysdk
SituationTypical generatorsteadysdk
API adds an endpointRewrites everythingAdds the new method; every other file is untouched
You wrote a custom helperGets deletedLives in your own file or a custom region; kept on every run
Someone hand-edits generated codeSilently overwrittenDetected; regeneration stops and tells you
An operationId is renamed upstreamYour method is renamed (breaking)Name pinned by the lock file until you opt in
The API changesYou diff the YAML by handsteadysdk diff lists every change and marks the breaking ones
Release notesWritten by handsteadysdk changelog writes them as Markdown or JSON
You are editing the specRe-run the generator by handsteadysdk watch regenerates on every save
CI—A GitHub Action fails when the SDK is stale, or on breaking changes without a major version bump

Built to be regenerated

  • Your code lives next to the generated code

    client.ts and index.ts are scaffolded once and never touched again, so helpers you add there survive every run.

  • Or inside it, in custom regions

    Generated files have named regions. Code between the markers is carried into every new version of the file, and generation stops rather than drop it.

  • Hand edits are detected, never lost

    The manifest records a hash of every file steadysdk wrote. If one changed outside its regions, generate stops and lists it.

  • Names stay put

    Every assigned name is recorded in names.lock.json. A renamed operationId keeps your method's name until you run generate --relock.

A custom region, kept on every run
// sdk/generated/api/pets.ts
export class PetsApi {
  // ...generated methods...

  // <steadysdk:custom members>
  async findAvailablePet(name: string, options?: RequestOptions): Promise<Pet | undefined> {
    const pets = await this.listPets({ status: ['available'] }, options);
    return pets.find((pet) => pet.name === name);
  }
  // </steadysdk:custom>
}

In pictures

The launch visuals, rendered from real output only.

  • steadysdk: typed TypeScript clients from OpenAPI that survive the 50th regeneration. Install with npm i -D @steadysdk/cli, then npx steadysdk init and generate.steadysdk
  • steadysdk diff output: 5 breaking and 7 non-breaking changes between Petstore 1.0.0 and 1.1.0, failing --require-bump.Breaking-change diff
  • A hand-written findAvailablePet helper inside a custom region of generated pets.ts, kept on every regeneration.Custom regions
  • Comparison table: what a typical generator does versus steadysdk in seven situations.vs typical generators
  • Six public specs, from GitHub to Kubernetes, generated and type-checked with 0 errors under the strictest tsconfig.Tested on real APIs
  • The GitHub Action workflow and its job summary failing a pull request on a breaking change without a major bump.CI gate

Tested on real APIs

Every SDK below is generated from the provider's published spec, pinned to a commit, and type-checked under the strictest compiler settings. A weekly workflow re-runs it.

SDKs generated from public API specs
APIOperationsSchemasGenerateStrict type-check
GitHub (OpenAPI 3.0)1,2329941.8 s0 errors
GitHub (OpenAPI 3.1, 274 webhooks)1,2329732.1 s0 errors
Stripe6121,5381.2 s0 errors
OpenAI3592,0480.9 s0 errors
Twilio1971500.4 s0 errors
Kubernetes (Swagger 2.0)1,1588161.1 s0 errors

Under the hood

Quick start
npm install --save-dev @steadysdk/cli
npx steadysdk init        # writes .steadysdkrc.yml
npx steadysdk generate    # writes ./sdk

Stack

  • TypeScript 7 and ESM
  • Node.js 22.19+
  • npm workspaces: an engine package and a CLI
  • Vitest
  • GitHub Actions

199 tests cover

  • Six real-world specs, regenerated by a weekly workflow
  • Golden snapshots of the example SDK and its changelog
  • Type-checks of the output under the strictest compiler flags
  • The runtime against a live local HTTP server
  • Watch mode and the GitHub Action against real repositories

Supported OpenAPI

  • OpenAPI 3.0 and 3.1, and Swagger 2.0; YAML or JSON
  • Files, URLs or git revisions
  • 3.1 webhooks
  • JSON, form, multipart, text and binary bodies
  • Bearer, basic, API keys, OAuth2 and OpenID Connect

Let's merge.

Have something like this in mind? A free 30-minute call gets you a rough scope and an honest estimate.