SDK commands
These commands generate SDKs from your API definition, keep generators up to date, and manage the custom code Fern Replay carries across regenerations. Creating a project with fern init and validating the API definition with fern check are general commands, and docs commands publish the API reference that documents the SDKs you generate. Each SDK command accepts the global options.
Detailed command documentation
fern generate
Use fern generate to run the Fern compiler and create SDKs for your API.
Remote generation (the default) requires authentication — the CLI prompts you to log in if needed, or you can set FERN_TOKEN. Self-hosted generation (--local) does not require login when writing to the local file system; GitHub output requires FERN_TOKEN or fern login.
target
Use --target <language> to generate one target from sdk-config.yml. The CLI reads sdk-config.yml from the API folder (fern/apis/<api>/), or from fern/ for a project with one API. Repeat --target to generate several targets, and combine it with --group to run legacy groups in the same run.
Without --group or --target, fern generate runs the legacy default group and every target in sdk-config.yml. --generator filters legacy groups only, so passing it with --target and no --group returns an error.
group
Use --group <group> to select a legacy generator group from generators.yml or generators.legacy.yml. Repeat --group to run several groups. You can use either a group name or an alias name. Aliases are defined in your generators.yml and map to multiple groups, allowing you to run several groups in parallel with a single command.
You can also set an alias as your default-group in generators.yml, so running fern generate without any arguments will run all groups in that alias.
The --group flag can be combined with other flags like --local for self-hosted SDK generation, --preview for local testing, or --version to specify the SDK version.
preview
Use --preview to test SDK changes locally before publishing. This is especially useful during development:
- Generates SDK into a local
.preview/folder - No changes are published to package managers or GitHub
Use --output <dir> with --preview to write the preview to a different directory. --output works only with --preview, and --preview can’t be combined with --package or --package-only.
api
Use --api <api> to specify the API for SDK generation. This is useful when your project contains multiple API definitions. The API name should match the directory name in your fern/apis/ folder.
Repeat --api to generate SDKs for several APIs. --api can’t be combined with --docs.
version
Use --version to specify the SDK version number, typically following semantic versioning (semver) format (MAJOR.MINOR.PATCH). This is particularly useful in CI/CD pipelines when publishing SDK releases.
fernignore
Use --fernignore to specify a custom .fernignore file path for SDK generation. This allows you to temporarily test different ignore configurations without modifying the committed .fernignore in your repository.
Fern will use the specified file instead of the one on the main branch and commit the new .fernignore to your repository as part of the generation process.
--fernignore works only for remote generation. It returns an error with --local or --runner, and can’t be combined with --skip-fernignore.
local
Use --local to run SDK generation on your own machine instead of using Fern’s cloud infrastructure. This is useful for organizations with strict security or compliance requirements. See self-hosted SDKs for setup instructions.
A Docker daemon must be running on your machine, as SDK generation runs inside a Docker container.
For legacy generators, the CLI pulls generator images from Docker Hub by default. To pull from a custom container registry, use the image field in your generators.yml instead of name. See custom container registry for details.
SDK Config targets run on Fern’s on-prem generator instead. Each language has a minimum generator version for local generation:
A target without generatorVersion runs the minimum version locally, while remote generation runs the newest version. Pinning generatorVersion below the minimum returns an error. Languages without an on-prem generator image fail with --local, and two targets with the same language can’t run locally in one run.
runner
Use --runner <docker|podman> to choose the container runtime for local generation. Passing --runner turns on local generation, the same as --local, so SDK Config targets run on the on-prem generator.
force
Use --force to skip confirmation prompts during generation. This is useful in CI/CD environments where interactive prompts would block the pipeline.
no-replay
Use --no-replay to skip Fern Replay’s patch detection and application phase for a single generation. The generation still produces the new SDK code, but tracked customization patches aren’t applied on top. Useful for a clean regeneration — for example, to debug whether a conflict is caused by a specific patch.
--no-replay applies to both local and remote generation, except for remote runs on Fern’s legacy generation service, which ignore it. The flag doesn’t appear in fern generate --help.
package
Use --package to build a distributable package artifact for every target or generator in the run that writes to the local file system: an sdk-config.yml target with output.delivery: files or a local run, or a legacy generator whose output location is local-file-system. Artifacts are written to a fern-dist/ folder inside that generator’s output directory, so a generated SDK can be handed to internal consumers without publishing it to a public registry. --package works with both cloud and local (--local) generation.
Not available for Swift.
package-mode
Use --package-mode <mode> to choose where --package runs the packaging toolchains. host (the default) uses the toolchains installed on the machine. docker runs each toolchain inside its official image with the output directory mounted, so no language toolchains are required locally, and uses docker as the container runtime unless you pass --runner podman.
--package-mode requires --package or --package-only.
package-only
Use --package-only to keep only the artifact: after packaging, everything in the output directory except fern-dist/ is deleted, so the generated SDK source isn’t left behind. --package-only implies --package.
Deletion happens per generator, so a generator that produced no artifact keeps its source. .git, .fernignore, and any top-level path a .fernignore entry covers are always preserved.
fern write-overrides
Use fern write-overrides to generate a basic OpenAPI overrides file. An overrides file allows for
reversible revisions to the API specification, including adding request and response examples for
code snippets in Fern Docs.
When run, this command creates a new file within fern/openapi/ called openapi-overrides.yml.
api
Use --api to specify the API to run the command on if multiple are defined.
exclude-models
Use --exclude-models to stub the models while generating the initial overrides (in addition to the endpoints).
fern generator upgrade
Use fern generator upgrade to update all generators in a legacy generators.yml to their latest versions. For sdk-config.yml targets, set the version with generatorVersion instead.
This is different from fern upgrade which updates the Fern CLI version. Use both commands to keep your entire Fern toolchain up to date.
This command will:
- Check for updates to all generators specified in your
generators.yml - Update the generator versions to their latest compatible releases
- Maintain compatibility with your current Fern compiler version
Here’s what you might see when updates are available:
list
Use --list to see the full list of generator upgrades available.
generator
Use --generator to specify a particular generator type to upgrade.
group
Use --group to upgrade generators within a specific group in your generators.yml. If not specified, all generators of the specified type will be upgraded.
include-major
Use --include-major to include major version upgrades. Major versions are skipped by default to prevent breaking changes.
fern replay resolve
Use fern replay resolve to work through patch conflicts that Fern Replay couldn’t merge cleanly during fern generate. The command runs in two phases: the first run applies unresolved patches to your working tree with standard merge markers (<<<<<<< / ======= / >>>>>>>) for you to edit; the second run verifies no markers remain and commits the resolved patches.
directory
Path to the SDK directory containing .fern/replay.lock. Defaults to the current directory.
no-check-markers
Skip the conflict-marker check before committing. Use with caution — committing files that still contain merge markers will break the next regeneration.
fern replay forget
Use fern replay forget to remove tracked customization patches from .fern/replay.lock. Useful when the generator now supports a customization natively, or when you want to stop replaying a specific edit on future regenerations.
The command accepts three modes:
-
By patch ID. Pass one or more patch IDs to remove specific patches.
-
By search pattern. Pass a pattern to find matching patches. The command shows the matches with diff stats and prompts for confirmation before removing.
-
All patches. Pass
--allto remove every tracked patch.
dry-run
Show what would be removed without actually removing.
yes
Skip confirmation prompts. Required in non-interactive or CI environments.