Generators

Fern | How to use Fern's TypeScript Node.js SDK Generator

Source code
Latest version: 0.9.5

The TypeScript Node.js SDK generator outputs a fully functional TypeScript/JavaScript SDK for server-side use. It can publish the SDK to npmjs.org (or any other Node package repository).

Local

Dump the generated SDK to the local file system. Available on the open source plan.

generators.yml
1groups:
2 local:
3 generators:
4 - name: fernapi/fern-typescript-node-sdk
5 version: 0.9.5
6 output:
7 location: local-file-system
8 path: ../generated/sdk/node

Publish an internal package

Publish the generated SDK to a private NPM hosted by Fern. Available on the Starter plan.

generators.yml
1groups:
2 internal:
3 generators:
4 - name: fernapi/fern-typescript-node-sdk
5 version: 0.9.5
6 output:
7 location: npm.buildwithfern.com
8 package-name: @fern-imdb/api # replace imdb with your org name

Publish a public package

Publish the generated SDK to npmjs.com. Available on the Starter plan.

generators.yml
1groups:
2 publish:
3 generators:
4 - name: fernapi/fern-typescript-node-sdk
5 version: 0.9.5
6 output:
7 location: npm
8 package-name: imdb # replace with your package name
9 token: ${NPM_TOKEN}
10 github:
11 repository: imdb/imdb-node # replace imdb with your org & package name

You can override the registry using the url key.

generators.yml
1generators:
2 groups:
3 public:
4 - name: fernapi/fern-typescript-node-sdk
5 version: 0.7.2
6 output:
7 location: npm
8 package-name: imdb # replace with your package name
9 token: ${NPM_TOKEN}
10+ url: your-npm-registry.com

Configuration options

You can customize the behavior of the TypeScript generator in generators.yml.

You can include one or more options for config, such as:

generators.yml
1- name: fernapi/fern-typescript-node-sdk
2 version: 0.9.5
3 output:
4 location: npm
5 package-name: imdb
6 github:
7 repository: imdb/imdb-node
8+ config:
9+ namespaceExport: IMDb
10+ timeoutInSeconds: 120
11+ noSerdeLayer: true
12+ outputEsm: true

The following options are available:

namespaceExport

  • namespaceExport: Allows you to control the name of the generated namespace export and client class. By default, the exported namespace and client are named based on the organization and API names in the Fern Definition.

Type: string

import { IMDbApi, IMDbApiClient } from "imdb";

To customize these names, you can use namespaceExport:

generators.yml
1- name: fernapi/fern-typescript-node-sdk
2 version: 0.9.5
3 output:
4 location: npm
5 package-name: imdb
6 github:
7 repository: imdb/imdb-node
8+ config:
9+ namespaceExport: IMDb

The result would be:

import { IMDb, IMDbClient } from "imdb";

defaultTimeoutInSeconds

  • defaultTimeoutInSeconds: Allows you to control the timeout of the generated client. The timeout is measured in seconds. This is useful for long-running operations. Set to "infinity" to disable timeouts.

Type: integer or "infinity"
Default: 60

1config:
2 timeoutInSeconds: 120
1config:
2 defaultTimeoutInSeconds: "infinity"

noSerdeLayer

  • noSerdeLayer: Allows you to control whether (de-)serialization code is generated. When true, the client uses JSON.parse() and JSON.stringify() instead.

Type: boolean
Default: false

By default, the generated client includes a layer for serializing requests and deserializing responses. This has three benefits:

  1. The client validates requests and response at runtime, client-side.

  2. The client can support complex types, like Date and Set.

  3. The generated types can stray from the wire/JSON representation to be more idiomatic. For example, when noSerdeLayer is disabled, all properties are camelCase, even if the server is expecting snake_case.

1config:
2 noSerdeLayer: true

outputESM

  • outputEsm: Allows you to control whether the generated TypeScript targets CommonJS or esnext.

Type: boolean
Default: false

By default, the generated TypeScript targets CommonJS. Set outputEsm to true to target esnext instead.

1config:
2 outputEsm: true

outputSourceFiles

  • outputSourceFiles: Allows you to control whether the generator outputs .js and d.ts files.

Type: boolean
Default: false

When disabled (the default), the generator outputs .js and d.ts files.

When enabled, the generator outputs raw TypeScript files.

This config is only applied when dumping the generated SDK to the local file system. It does not apply when publishing to GitHub or npm.

1config:
2 outputSourceFiles: true

includeCredentialsOnCrossOriginRequests

  • includeCredentialsOnCrossOriginRequests: Allows you to set withCredentials to true when making network requests.

Type: boolean
Default: false

To set withCredentials to true when making network requests, set this config to true.

1config:
2 includeCredentialsOnCrossOriginRequests: true

allowCustomFetcher

  • allowCustomFetcher: Allows the end user to specify a custom fetcher implementation.

Type: boolean
Default: false

1config:
2 allowCustomFetcher: true
1const imdb = new IMDbClient({
2 fetcher: (args) => {
3 ...
4 },
5});

requireDefaultEnvironment

  • requireDefaultEnvironment: When enabled, the generated client doesn’t allow the user to specify a server URL.

Type: boolean
Default: false

1config:
2 requireDefaultEnvironment: true

When disabled (the default), the generated client includes an option to override the server URL:

1const imdb = new IMDbClient({
2 environment: "localhost:8080",
3});

skipResponseValidation

  • skipResponseValidation: When enabled, the generated client will never throw if the response is misshapen. Rather, the client will log the issue using console.warn and return the data (cast to the expected response type).

Type: boolean
Default: false

By default, this config is set to false and the client will throw an error if the response from the server doesn’t match the expected type (based on how the response is modeled in the API definition). Set this config to true to never throw an error and log the issue instead.

1config:
2 skipResponseValidation: true

extraDependencies

  • extraDependencies: Allows you to specify extra dependencies in the generated package.json.

Type: map<string,string>
Default: {}

This only applies when publishing to GitHub.

You can use extraDependencies to specify extra dependencies in the generated package.json. This is useful when you utilize .fernignore to supplement the generated client with custom code.

1config:
2 extraDependencies:
3 jest: "^29.7.0" # <-- examples
4 "@types/jest": "^29.5.5"
5 ts-jest: "^29.1.1"

treatUnknownAsAny

  • treatUnknownAsAny: When enabled, unknown types from Fern are generated into TypeScript using any.

Type: boolean
Default: false

In Fern, there’s an unknown type that represents data that isn’t knowable at runtime. By default, these types are generated into TypeScript as the unknown type.

1config:
2 treatUnknownAsAny: true

noOptionalProperties

  • noOptionalProperties: Allows you to prevent generating optional properties.

Type: boolean
Default: false

When enabled, the generated properties are never optional. Instead, the type is generated with | undefined.

For example, let’s say you have the following Fern Definition:

person.yml
1types:
2 Person:
3 properties:
4 name: string
5 age: optional<integer>

By default, Fern’s optional<> properties translate to optional TypeScript properties:

1interface Person {
2 name: string;
3 age?: number;
4}

When noOptionalProperties is enabled (set to true):

1interface Person {
2 name: string;
3 age: number | undefined;
4}

useBrandedStringAliases

  • useBrandedStringAliases: When enabled, string aliases are generated as branded strings. This makes each alias feel like its own type and improves compile-time safety.

Type: boolean
Default: false

For example, let’s say you have the following Fern Definition:

movies.yml
1types:
2 MyString: string
3 OtherString: string
generated code
1export type MyString = string & { __MyString: void };
2export const MyString = (value: string): MyString => value as MyString;
3
4export type OtherString = string & { __OtherString: void };
5export const OtherString = (value: string): OtherString => value as OtherString;
consuming the generated type
1function printMyString(s: MyString): void {
2 console.log("MyString: " + s);
3}
4
5// doesn't compile, "foo" is not assignable to MyString
6printMyString("foo");
7
8const otherString = OtherString("other-string");
9// doesn't compile, otherString is not assignable to MyString
10printMyString(otherString);
11
12// compiles
13const myString = MyString("my-string");
14printMyString(myString);

When useBrandedStringAliases is disabled (the default), string aliases are generated as normal TypeScript aliases:

generated code
1export type MyString = string;
2
3export type OtherString = string;

neverThrowErrors

  • neverThrowErrors: When enabled, the client doesn’t throw errors when a non-200 response is received from the server. Instead, the response is wrapped in an ApiResponse.

Type: boolean
Default: false

APIResponse.ts
1const response = await client.callEndpoint(...);
2if (response.ok) {
3 console.log(response.body)
4} else {
5 console.error(response.error)
6}