Migrating to SDK Config
Use fern sdk migrate to move SDK generation from generators.yml to sdk-config.yml and adopt the new SDK generators. You can migrate every language at once or one language at a time, and spread targets across more than one SDK Config file. A project that doesn’t run fern sdk migrate keeps generating from generators.yml.
The migration keeps your original configuration as comments in generators.legacy.yml, so you can roll back.
Why migrate
generators.yml names the generator to run, its version, and its generator-specific options. sdk-config.yml describes the SDK you want instead: the API source, shared client behavior, package identity, delivery, publishing, and target languages. You declare shared settings once, every target inherits them, and language-specific differences are explicit overrides. Adding an SDK means adding a language target.
For migrated targets, sdk-config.yml owns SDK generation, and docs.yml continues to own your docs site. The migration doesn’t change docs.yml. generators.legacy.yml holds only the targets you haven’t migrated and the rollback comments.
Migration states
A project is in one of these states:
- Not migrated: The project has only
generators.ymland generates as before, for example withfern generate --api plant-store --group public. - Partially migrated:
generators.legacy.ymlholds the active legacy targets and the rollback comments, andsdk-config.ymlholds the migrated targets. For example, Python stays on its pinned generator while TypeScript uses the newest TypeScript generator. - Fully migrated:
sdk-config.ymlholds every compatible SDK target, andgenerators.legacy.ymlkeeps the original configuration as comments. - Multiple SDK Configs: The project has more than one SDK Config file, such as
sdk-config.ymlandsdk-config.internal.yml, and can configure the same language in each. Select a file with--sdk-config.
Before you start
Upgrade the Fern CLI
Migration requires a recent Fern CLI version. Upgrade both the installed CLI and the version pinned in fern.config.json to the most recent release:
Installing a newer CLI globally isn’t enough on its own, because the CLI runs the version pinned in fern.config.json. If fern --version still reports an older version, check your organization’s CLI version policy with fern org get --json. An admin might need to raise the maximum version.
Don’t run fern generator upgrade during a partial migration. It can change the generator versions pinned for languages that stay on generators.yml. After you upgrade the CLI, confirm that their version fields haven’t changed.
Log in
Run fern login before you preview or generate. In CI, set the FERN_TOKEN environment variable instead. See fern generate for details.
Migrate one language
These steps migrate TypeScript from a public group that also contains Python, and leave Python on its current generator.
Preview the migration
A dry run validates the migration and lists the file operations it would perform:
A dry run doesn’t show the full file changes. To inspect them, run the migration on a branch.
Run the migration
There’s no --apply flag; the command changes files unless you pass --dry-run. It renames generators.yml to generators.legacy.yml, creates sdk-config.yml or merges into an existing one, comments out the TypeScript invocation, leaves Python active at its existing version, and prints rollback instructions.
The generated sdk-config.yml also contains the API source, SDK name, output configuration, and the settings migrated from your project.
Migrate more languages or groups
To migrate several languages, repeat --language:
To migrate every compatible SDK generator in a group, omit --language. The command leaves non-SDK and unsupported generators active and reports them. When you migrate a whole group, the command comments out the group and adjusts default-group and aliases so the remaining legacy configuration stays valid, keeping their original values in comments.
To migrate several groups into one file, repeat --group. The groups must use compatible API sources and different languages.
Review the configuration
Review the changes before you generate:
Confirm that:
- The remaining legacy generators are active and keep their pinned versions.
- The migrated generator invocations are comments.
sdk-config.ymlcontains only the targets you meant to migrate.- The API source paths, output, and publishing configuration are correct.
- The credential environment variables that publishing needs are available.
docs.ymlis unchanged.
Choose a generator version
The migration doesn’t copy the legacy generator version into sdk-config.yml. A target without generatorVersion uses the newest supported generator for its language. To pin a version, set generatorVersion to a version that supports SDK Config:
Don’t copy a legacy generator version into generatorVersion. The CLI rejects versions older than the first version of that language’s generator that supports SDK Config.
fern generate --version sets the version of the generated SDK package, not the generator version.
Validate and preview
Validate the migrated project, then preview the migrated target:
A preview runs Fern’s remote generation, writes the output locally, and doesn’t publish.
Generate
Generate a migrated target with --target:
Generate the languages that stay on generators.yml with --group. The group runs only its active generators, so the commented-out TypeScript generator doesn’t run:
To generate both in one command, pass --group and --target. Fern runs the legacy and SDK Config targets as separate jobs, which can run at the same time.
Pass --group or --target explicitly while you migrate. Without them, fern generate runs the default legacy group and every target in the default sdk-config.yml.
Use more than one SDK Config file
To create or merge into a different file, pass --output:
Generate from it with --sdk-config:
Separate SDK Config files can configure the same language, but each file can contain only one target per language. The migration comments in generators.legacy.yml record which SDK Config file owns each migrated target.
Migrate the next language
To migrate Python later, preview and run the migration again:
The CLI merges Python into the existing sdk-config.yml when the API source and shared settings are compatible. If they aren’t, write Python to a separate file with --output ./fern/apis/plant-store/sdk-config.python.yml.
Running the migration for a target that’s already migrated leaves the files unchanged and reports that the target is already migrated. Treat this as a configuration error, not a successful run.
Update CI/CD
Replace --group with --target in generation commands for migrated languages:
For a partial migration, pass both:
For a different SDK Config file, add --sdk-config. Make sure CI sets FERN_TOKEN and any publishing credentials that the selected targets reference.
Roll back
Because the original generator versions and settings stay in comments, you can restore the previous configuration without rewriting it.
Roll back one language
- Remove the language’s target from
sdk-config.yml. - Uncomment its original invocation in
generators.legacy.yml. Keep the file namegenerators.legacy.ymlwhile other targets usesdk-config.yml. - Generate the legacy group:
fern generate --api plant-store --group public.
Roll back the entire migration
- Delete the SDK Config file, or remove every migrated target from it.
- Rename
generators.legacy.ymltogenerators.yml. - Uncomment the original groups, generator invocations,
default-group, and aliases. - Run your original generation command, such as
fern generate --api plant-store --group public.
Limitations
Contact Fern support if:
- Your project uses a Fern Definition, protobuf, OpenRPC, or Conjure source, which
fern sdk migratedoesn’t support yet. - Your API specification comes from a Git repository and can’t be referenced by a local path.
- The groups you’re merging use different API sources, import settings, audiences, or incompatible shared SDK settings.
- Your publishing credentials can’t be referenced as environment variables.
- Your organization’s CLI version policy prevents upgrading to a Fern CLI version that supports migration.
To roll out with the least risk, upgrade the CLI, migrate one language, preview it, check its SDK output, and update CI before you migrate the next language.