Compiler
fern generate

You can run the fern compiler using the Fern CLI:

fern generate --group <group name>

TL;DR: generators.yml controls what Fern will generate for you. fern generate validates your API and runs generators in the cloud in isolated, containerized environments. You can view the list of available generators here.

A modular compiler

Unlike most compilers, the Fern compiler does not produce a single output. Here are some examples of what the Fern compiler can output:

  • A TypeScript SDK
  • FastAPI boilerplate
  • A Postman Collection
  • An OpenAPI spec

To support the long and growing list of outputs, we’ve built the Fern Compiler to be modular. The core compiler is responsible for parsing and validating your Fern Definition, and producing the intermediate representation.

The remaining work is handled by generators. A Fern generator is a program that takes in an intermediate representation and outputs… something. Generators can be written in any language.

You specify which generators you want the compiler to run using the special file generators.yml. You can view the list of available generators here.

fern/
├─ fern.config.json
└─ api/
  ├─ generators.yml # <---
  └─ definition/
    ├─ api.yml
    └─ imdb.yml

generators.yml

Check out a real example of generators.yml.

In generators.yml, you separate generators into groups.

generators.yml
groups:
  # we run the FastAPI generator for server-side development
  server:
    generators:
      - name: fernapi/fern-fastapi-server
        version: 0.0.33
        output:
          location: local-file-system
          path: ../../app/fern/server
  # on every commit into the main branch, we generate SDKs for internal use
  internal:
    generators:
      - name: fernapi/fern-typescript-node-sdk
        version: 0.0.249
        output:
          location: npm
          package-name: "@fern-api/plantstore"
          token: ${NPM_TOKEN}
      - name: fernapi/fern-java-sdk
        version: 0.0.125
        output:
          location: maven
          coordinate: io.github.fern-api:plantstore
          username: ${MAVEN_USERNAME}
          password: ${MAVEN_PASSWORD}
  # when we release, we publish our external-facing SDKs
  external:
    generators:
      - name: fernapi/fern-typescript-node-sdk
        version: 0.0.249
        github:
          repository: my-org/node-sdk

You can run the fern compiler for a particular group using the Fern CLI:

fern generate --group <group name>

This validates your API and runs generators in the cloud in isolated, containerized environments.

You can also specify a default-group in generators.yml:

generators.yml
default-group: server
groups:
  server: ...

Then, you can just run fern generate to run the server generator(s).


Generator schema

In this section, we’ll detail the different properties you need to include for a generator.

Name

Each generator has a unique name, e.g. fernapi/fern-typescript-node-sdk.

generators.yml
groups:
  external:
    generators:
      - name: fernapi/fern-typescript-node-sdk # <---

Version

You must specify which version of the generator you want to use. This helps ensure consistent builds.

generators.yml
groups:
  external:
    generators:
      - name: fernapi/fern-typescript-node-sdk
        version: 0.0.249 # <---

Configuration

Some generators allow for custom configuration, which you can specify using the optional config key.

generators.yml
 groups:
   external:
       - name: fernapi/fern-openapi
         version: 0.0.11-4-g1c29f6c
         github:
           repository: fern-api/plantstore-openapi
+        config:
+          format: yaml

Output locations

You can optionally specify an location for the generated output. There are currently five supported output locations:

  • npm registry
  • Maven repository
  • PyPI registry
  • postman.com collection
  • local filesystem output

npm registry

For generators that output a TypeScript/JavaScript package, you can publish the generated code directly to npm.

generators.yml
groups:
  external:
    generators:
      - name: fernapi/fern-typescript-node-sdk
        version: 0.0.249
        output: # <---
          location: npm
          package-name: your-package-name
          token: ${NPM_TOKEN}

By default, Fern publishes to npmjs.com. You can override the registry using the url key.

generators.yml
 groups:
   external:
     generators:
       - name: fernapi/fern-typescript-node-sdk
         version: 0.0.249
         output:
           location: npm
           package-name: your-package-name
           token: ${NPM_TOKEN}
+          url: your-npm-registry.com

Maven repository

For generators that output a Java package, you can publish the generated code to a Maven repository.

generators.yml
groups:
  external:
    generators:
      - name: fernapi/fern-java-sdk
        version: 0.0.125
        output: # <---
          location: maven
          coordinate: com.your-coordinate
          username: ${MAVEN_USERNAME}
          password: ${MAVEN_PASSWORD}

By default, Fern publishes to Maven Central. You can override the registry using the url key.

generators.yml
 groups:
   external:
     generators:
       - name: fernapi/fern-java-sdk
         version: 0.0.125
         output:
           location: maven
           coordinate: com.your-coordinate
           username: ${MAVEN_USERNAME}
           password: ${MAVEN_PASSWORD}
+          url: your-maven-repo.com

PyPI registry

For generators that output a Python package, you can publish the generated code directly to PyPI.

generators.yml
groups:
  external:
    generators:
      - name: fernapi/fern-python-sdk
        version: 0.1.0
        output: # <---
          location: pypi
          package-name: your-package-name
          token: ${PYPI_TOKEN}

By default, Fern publishes to pypi.org. You can override the registry using the url key.

generators.yml
 groups:
   external:
     generators:
       - name: fernapi/fern-python-sdk
         version: 0.1.0
         output:
           location: pypi
           package-name: your-package-name
+          username: your-username
+          password: ${PYPI_PASSWORD}
+          url: your-pypi.com

postman.com collection

The Postman generator can publish directly to your postman.com workspace.

generators.yml
groups:
  external:
    generators:
      - name: fernapi/fern-postman
        version: 0.0.31
        output: # <---
          location: postman
          api-key: ${POSTMAN_API_KEY}
          workspace-id: ${POSTMAN_WORKSPACE_ID}

To find your workspace ID, select the ⓘ icon in the top right of the workspace view.

Postman Workspace ID

Local filesystem output

You can always output the generated files to disk. This is helpful for local development, or for when you want to quickly introspect the generated files.

generators.yml
groups:
  server:
    generators:
      - name: fernapi/fern-fastapi-server
        version: 0.0.33
        output: # <---
          location: local-file-system
          path: ../../app/fern/server

GitHub publishing

Fern can publish the generator’s output to a GitHub repo. It can be useful to have a dedicated repo for an output to track issues and its history over time.

For an example, check out Flipt’s Node.js SDK repo.

When you run the compiler with fern generate, Fern will re-generate the Github repo and push to the main branch.

generators.yml
groups:
  external:
    generators:
      - name: fernapi/fern-typescript-node-sdk
        version: 0.0.249
        github: # <---
          repository: my-org/node-sdk

Combining with output

You can combine the output and github options. If you do, the generated GitHub repo will include a GitHub workflow that publishes the source code to its output destination.

For an example, check out Flipt’s GitHub workflow.

generators.yml
 groups:
   external:
     generators:
       - name: fernapi/fern-typescript-node-sdk
         version: 0.0.249
+        output:
+          location: npm
+          package-name: your-package-name
+          token: ${NPM_TOKEN}
         github:
           repository: my-org/node-sdk

When you run the compiler with fern generate, Fern will:

  1. Re-generate the Github repo and push to the main branch
  2. Tag a release on the generated repo. This will trigger the GitHub workflow to publish to the output location (e.g. npm)

.fernignore

When you run the compiler with fern generate, Fern will re-generate the entire repo and delete any files it doesn’t recognize.

If you’d like for Fern to ignore certain files, use .fernignore. This is simlar to .gitignore. Any files you list here will be ignored by Fern.

For an example, check out Flipt’s .fernignore.

Tip: it’s common to list README.md in your .fernignore so that Fern doesn’t wipe it out.