Migration guides

Keep a Stainless-Generated SDK After the Generator Stops

You own the SDK repo, the published packages, and every line Stainless generated for you — Stainless said so directly when it announced it was joining Anthropic on 2026-05-18: "you own the SDKs you've generated to date, and have full rights to modify and extend them however you wish." What stopped that day was new generation: "Starting today, new signups, projects, and SDKs will not be available." Your repo still works. The question is how you keep shipping it. Three paths: hand-maintain the last generated output, switch to a different generator after diffing the surface, or move to a hosted replacement. Which one fits depends on your release frequency and how many languages you ship.

What's actually in your Stainless-generated repo

Before picking a path, inventory what you have. Every Stainless-generated SDK repo carries the same markers:

  • .stats.yml — the file that identifies a repo as Stainless-managed. It records configured_endpoints (how many operations are generated) and the source OpenAPI spec location. A real example from val-town/sdk shows this is the first thing to check — it tells you how much surface area you're responsible for.
  • stainless.yml (or the equivalent config in your Docs Platform project) — package names, production repo targets, auth env-var naming, README example endpoints, and your full resource tree. This file is portable; see what stainless.yml actually controls if you're not sure which parts matter.
  • Generated vs. custom code, interleaved. Stainless merges your hand-written customizations into generated files with a semantic three-way merge rather than keeping them in separate directories. That's convenient while the generator runs and awkward the moment it doesn't — you can't just "regenerate the generated part," because there's no clean seam.
  • Release config and CI secrets. The GitHub Actions (or equivalent) workflow that tags releases and publishes to npm/PyPI, plus whatever tokens or trusted-publisher config authorize that workflow.
  • Package names and production repo targets, already live on npm, PyPI, or wherever else you publish.

Write this down as a checklist before you decide anything — which files are generated, which are hand-edited, where releases are cut from, what CI secrets exist. That inventory is the actual deliverable of this post; everything below is just what to do with it.

Path 1: hand-maintain the last generated output

If your API changes rarely and you ship one or two languages, this is often the least work. You freeze the last Stainless-generated commit as your new baseline and edit it directly going forward — new endpoints get added by hand, following the pattern the generator used.

This works well when:

  • Your API adds maybe one or two endpoints a quarter.
  • You ship a single language (or the interleaved custom code is minimal).
  • Nobody on the team needs to touch generated internals often enough to make manual editing a bottleneck.

It breaks down when your API changes weekly, because every new endpoint is now a manual diff against your own memory of the generated pattern, with no regeneration step to catch drift between your SDK and your spec.

Path 2: switch generators, diff the surface first

If hand-maintenance won't scale, point a different generator at your existing OpenAPI spec and compare the output to what you're shipping today — before you cut over.

The two most-cited free options for teams leaving Stainless:

  • OpenAPI Generator — Apache-2.0, community-maintained, supports the widest language spread from one config format. No vendor risk, but you'll write custom templates and a post-processing step to match your existing method names and package shape.
  • A hosted hand-off — several platforms (see below) read stainless.yml directly, which shortens the config-mapping step but still requires a surface diff before you trust the output.

Whichever generator you pick, the check that matters is the same: diff the generated package surface against your last Stainless output — method names, parameter types, pagination helpers, error classes, README examples — before you publish anything with the new tooling. A generator that "runs successfully" is not the same as a generator that produces the SDK your customers already depend on. Sourced's compatibility report is built for exactly this comparison: it reads your stainless.yml, generates a TypeScript and Python preview from the same spec, and reports missing methods, changed signatures, and anything that needs a human look — before you touch a customer-facing package. See the Stainless-to-Sourced walkthrough for the four-step version of this path.

Path 3: move to a hosted replacement

If you don't want to own the generation pipeline at all, several platforms are pitched as Stainless replacements as of September 2026. WorkOS's rundown and Scalar's wind-down write-up both cover the field — evaluate any of them (including Sourced) on the same three questions: does it read your existing stainless.yml or require a from-scratch config, does it generate every language you currently ship, and does it give you a surface diff before publish, or just a fresh generation you have to eyeball yourself. Sourced covers the first and third directly — TypeScript and Python are fully managed, with a compatibility report on every run — and generates Java, Go, Rust, and Ruby as Scale-plan preview downloads (no publish automation yet for those four). If your Stainless project shipped a language outside that list, confirm coverage before you commit to any hosted option, not just this one.

Which path fits your team

Signal Hand-maintain Switch generator Hosted replacement
Release cadence Quarterly or slower Monthly, tolerant of a setup project Weekly or faster
Languages shipped 1 1-2, willing to configure templates 2+
Team has spare eng time for a generator migration No Yes Doesn't matter
Want a surface diff before every future release, not just this one No Only if you build it yourself Yes, if the platform offers it

FAQ

Did Stainless set an end date for existing customer repos and packages?

No. As of this writing, Stainless has not published a shutdown date for SDKs already generated and published. The announcement stops new signups, projects, and generation as of 2026-05-18, but says nothing about pulling existing packages from npm or PyPI, and you retain full rights to the code either way.

Can I keep using my Stainless-generated repo forever without changing anything?

Only if your API never changes. The moment you add an endpoint or change a response shape, your SDK and your API drift apart unless someone — you, by hand, or a generator — updates the SDK to match. "Do nothing" is not a fourth path; it's Path 1 with a release cadence of zero, which only works until it doesn't.

Does switching generators mean rewriting my public method names?

Not necessarily. A generator diff should be able to match your existing method names, parameter shapes, and pagination helpers closely if you configure it to — that's the point of diffing the surface before cutover instead of after. Expect some manual template work to close the gap, not a full rewrite.

What's the fastest way to check whether my stainless.yml will port cleanly to a new tool?

Read what each field actually controls first — see OpenAPI vs stainless.yml: what each actually controls — then run your spec and config through the new tool's preview mode (if it has one) before touching a production repo. Create a hosted docs preview from your repo is the fastest way to see what a spec-plus-config pair produces without publishing anything.

Is hand-maintaining a generated SDK actually sustainable long-term?

For a slow-moving API, yes — plenty of teams do it for years. The risk isn't sustainability, it's drift: without a generator or a diff step, nothing catches the day your SDK quietly stops matching your API. If you go this route, put a periodic manual audit against your live OpenAPI spec on the calendar.

What to do this week

  • Pull your repo's .stats.yml and stainless.yml and write the inventory above — generated paths, custom paths, release config, CI secrets, package names. Do this before your next planned release, not during it.
  • Decide your path using the table above. Don't default to "switch generators" just because it feels more thorough — hand-maintenance is genuinely the right call for a slow-moving API.
  • If you're evaluating a generator switch or a hosted replacement, get a surface diff before you publish anything. Start a free Sourced report against your existing spec and stainless.yml — TypeScript and Python previews plus a compatibility report are free to try, no credit card, and the report is the artifact that tells you whether a switch is actually safe.

Whatever you pick, the repo and the packages already published are yours either way — that part of the Stainless wind-down was never in question.