This repository contains a complete Fern configuration that generates SDKs and a CLI from a single OpenAPI spec. Use it as a template to see how Fern turns an API definition into production-ready, published client libraries.
Every push to main triggers GitHub Actions that call fern generate to produce:
| Output | Repository | Published to |
|---|---|---|
| TypeScript SDK | petstore-typescript-sdk | npm (@fern-api/example-typescript-sdk-petstore) |
| Rust SDK | petstore-rust-sdk | crates.io (petstore) |
| CLI | petstore-cli | npm (@fern-api/example-cli-petstore) |
Additional generators for Python, Go, Java, C#, and Ruby are included in generators.yml as commented-out blocks — uncomment what you need.
fern/
├── openapi.yml # PetStore OpenAPI 3.0 spec (the source of truth)
├── generators.yml # Fern generator config — defines which SDKs to generate
└── fern.config.json # Fern project config (org + CLI version)
.github/workflows/
├── fern-check.yml # Validates the spec on every PR
├── ts-sdk.yml # Generates + publishes the TypeScript SDK
├── rust-sdk.yml # Generates + publishes the Rust SDK
├── cli.yml # Generates + publishes the CLI
├── python-sdk.yml.example # Template — rename to .yml when python-sdk is uncommented
├── go-sdk.yml.example # Template — rename to .yml when go-sdk is uncommented
├── java-sdk.yml.example # Template — rename to .yml when java-sdk is uncommented
├── csharp-sdk.yml.example # Template — rename to .yml when csharp-sdk is uncommented
└── ruby-sdk.yml.example # Template — rename to .yml when ruby-sdk is uncommented
- Define your API — Write or import an OpenAPI spec into
fern/openapi.yml. - Configure generators — In
fern/generators.yml, declare which SDKs and CLIs to generate, where to publish them, and which GitHub repos receive the generated code. - Add a workflow — Each generator group needs a GitHub Actions workflow. Workflow templates for every supported language are included in
.github/workflows/. - Push to
main— GitHub Actions first run a preview generation (fern generate --group <group-name> --preview) and validate the output (build + test), then run the realfern generateto publish.
Note: Generation requires a
FERN_TOKENtied to your Fern organization. The token authenticates with Fern's generation service and controls access to paid features like auto-publishing, pagination, retries, and OAuth support.
To enable a new SDK (for example, Python):
- Uncomment the group in
fern/generators.yml:python-sdk: generators: - name: fernapi/fern-python-sdk version: 5.14.8 output: location: pypi package-name: petstore-sdk github: repository: your-org/petstore-python-sdk mode: release config: client: class_name: PetstoreClient
- Update the placeholders — Set your
package-name,repository, andclientclass name. - Create the target GitHub repo (e.g.
your-org/petstore-python-sdk) and install the Fern GitHub App on it. - Add
FERN_TOKEN— In your config repo's Settings → Secrets, add your Fern token. This is the only secret required — Fern handles registry authentication via OIDC. - Activate the workflow template — Rename
.github/workflows/python-sdk.yml.exampletopython-sdk.ymland add the push trigger so it runs on changes tomain:Seeon: push: branches: - main paths: - "fern/openapi.yml" - "fern/openapi-overlay.yml" - "fern/fern.config.json" - "fern/generators.yml" workflow_dispatch:
ts-sdk.ymlfor a complete example. - Push to
main— The workflow runs automatically.
- Fork this repo (or copy the
fern/folder into your own project). - Replace
fern/openapi.ymlwith your own OpenAPI spec. - Update
generators.yml— rename packages, pointgithub.repositoryto your own repos, and uncomment the languages you want. - Sign up for Fern and generate a token:
npm install -g fern-api fern token
- Add
FERN_TOKENas a GitHub Actions secret (Settings → Secrets → Actions). This is the only secret you need — Fern handles registry publishing via OIDC. - Push to
main— your SDKs are generated and published automatically.
Install the Fern CLI:
npm install -g fern-apiValidate the configuration:
fern checkPreview what would be generated (outputs to your local filesystem):
fern generate --group ts-sdk --local