# Typescript Configuration Options
Source: https://speakeasy.com/docs/speakeasy-reference/generation/ts-config

import { Table, Callout } from "@/mdx/components";




 This section details the available configuration options for the TypeScript SDK. All configuration is managed in the `gen.yaml` file under the `typescript` section.

## Version and general configuration

```yml
typescript:
  version: 1.2.3
  author: "Author Name"
  packageName: "custom-sdk"
```

<Table 
  data={[
    { name: "version", required: "true", default: "0.0.1", description: "The current version of the SDK." },
    { name: "packageName", required: "true", default: "openapi", description: "The name of the npm package. See [npm package guidelines](https://docs.npmjs.com/package-name-guidelines)." },
    { name: "author", required: "true", default: "Speakeasy", description: "The name of the author of the published package. See [npm author field](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#people-fields-author-contributors)." }
  ]}
  columns={[
    { key: "name", header: "Name" },
    { key: "required", header: "Required" },
    { key: "default", header: "Default Value" },
    { key: "description", header: "Description" }
  ]}
/>

## Additional JSON package

```yml
typescript:
  additionalPackageJSON:
    license: "MIT"
```

<Table 
  data={[
    { name: "additionalPackageJSON", required: "false", default: "{}", description: "Additional key/value pairs for the `package.json` file. Example: license, keywords, etc." }
  ]}
  columns={[
    { key: "name", header: "Name" },
    { key: "required", header: "Required" },
    { key: "default", header: "Default Value" },
    { key: "description", header: "Description" }
  ]}
/>

## Additional dependencies

```yml
typescript:
  additionalDependencies:
    dependencies:
      axios: "^0.21.0"
    devDependencies:
      typescript: "^4.0.0"
    peerDependencies:
      react: "^16.0.0"
```

<Table 
  data={[
    { name: "dependencies", required: "false", default: "{}", description: "Additional production dependencies to include in the `package.json`." },
    { name: "devDependencies", required: "false", default: "{}", description: "Additional development dependencies to include in the `package.json`." },
    { name: "peerDependencies", required: "false", default: "{}", description: "Peer dependencies for compatibility." }
  ]}
  columns={[
    { key: "name", header: "Name" },
    { key: "required", header: "Required" },
    { key: "default", header: "Default Value" },
    { key: "description", header: "Description" }
  ]}
/>

## Package scripts and examples

```yml
typescript:
  additionalScripts:
    format: "prettier --write src"
    docs: "typedoc --out docs src"
    custom-test: "vitest run --coverage"
  generateExamples: true
  compileCommand: ["npm", "run", "build"]
  usageSDKInit: "new Petstore({})"
  usageSDKInitImports:
    - package: "@petstore/sdk"
      import: "Petstore"
      type: "packageImport"
```

<Table 
  data={[
    { name: "additionalScripts", required: "false", default: "{}", description: "Custom npm scripts to add to the `package.json` file. Scripts with the same name as default scripts will override them." },
    { name: "generateExamples", required: "false", default: "true", description: "Whether to generate example files in an examples directory demonstrating SDK usage." },
    { name: "compileCommand", required: "false", default: "N/A", description: "The command to use for compiling the SDK. Must be an array where the first element is the command and the rest are arguments." },
    { name: "usageSDKInit", required: "false", default: "N/A", description: "The SDK initialization code to use in usage examples (e.g., `new Petstore({})`)." },
    { name: "usageSDKInitImports", required: "false", default: "[]", description: "Array of imports to add when `usageSDKInit` is configured. Each import should have `package`, `import`, and optionally `type` fields (options: `typeImport`, `packageImport`, `aliasImport`)." }
  ]}
  columns={[
    { key: "name", header: "Name" },
    { key: "required", header: "Required" },
    { key: "default", header: "Default Value" },
    { key: "description", header: "Description" }
  ]}
/>

### How scripts are merged

The feature uses an override strategy where additional scripts take precedence over default scripts:

1. **Default scripts** are generated automatically based on SDK configuration:

```json
{
  "lint": "eslint --cache --max-warnings=0 src",
  "build": "tsc",
  "prepublishOnly": "npm run build"
}
```

2. **Test scripts** are added if tests are enabled:

```json
{
  "test": "vitest run src --reporter=junit --outputFile=.speakeasy/reports/tests.xml --reporter=default",
  "check": "npm run test && npm run lint"
}
```

3. **Additional scripts** override defaults if they have the same name:

```yml
typescript:
  additionalScripts:
    build: "custom-build-command"  # Replaces default "tsc" build
    deploy: "npm publish"           # Adds new script
```

4. **Result** in `package.json`:

```json
{
  "scripts": {
    "build": "custom-build-command",  // Overridden
    "check": "npm run test && npm run lint",
    "deploy": "npm publish",           // Added
    "lint": "eslint --cache --max-warnings=0 src",
    "prepublishOnly": "npm run build",
    "test": "vitest run src --reporter=junit --outputFile=.speakeasy/reports/tests.xml --reporter=default"
  }
}
```

## Method and parameter management

```yml
typescript:
  maxMethodParams: 3
  flatteningOrder: "parameters-first"
  methodArguments: "infer-optional-args"
```

<Table 
  data={[
    { name: "[maxMethodParams](/docs/sdks/customize/methods)", required: "false", default: "0", description: "Maximum number of parameters before an input object is created. `0` means input objects are always used." },
    { name: "[flatteningOrder](/docs/sdks/customize/methods#configuring-method-signatures)", required: "false", default: "parameters-first", description: "Determines the ordering of method arguments when flattening parameters and body fields. Options: `parameters-first` or `body-first`." },
    { name: "methodArguments", required: "false", default: "infer-optional-args", description: "Determines how arguments for SDK methods are generated. If set to `infer-optional-args`, the method argument will be optional when all parameters and the request body are optional. Options: `infer-optional-args` or `require-security-and-request`." }
  ]}
  columns={[
    { key: "name", header: "Name" },
    { key: "required", header: "Required" },
    { key: "default", header: "Default Value" },
    { key: "description", header: "Description" }
  ]}
/>

## Security configuration

```yml
typescript:
  envVarPrefix: SPEAKEASY
  flattenGlobalSecurity: true
```

<Table 
  data={[
    { property: "[flattenGlobalSecurity](/docs/customize/authentication/overview)", description: "Enables inline security credentials during SDK instantiation. **Recommended: `true`**", type: "boolean", default: "true" },
    { property: "envVarPrefix", description: "Sets a prefix for environment variables that allows users to configure global parameters and security.", type: "string", default: "N/A" }
  ]}
  columns={[
    { key: "property", header: "Property" },
    { key: "description", header: "Description" },
    { key: "type", header: "Type" },
    { key: "default", header: "Default" }
  ]}
/>

## Module management

```yml
typescript:
  moduleFormat: "dual"
  useIndexModules: true
```

<Table 
  data={[
    { name: "[useIndexModules](/docs/sdks/customize/typescript/disabling-barrel-files)", required: "false", default: "true", description: "Controls generation of index modules (`index.ts`). Setting to `false` improves tree-shaking and build performance by avoiding barrel files." },
    { name: "[moduleFormat](/docs/sdks/customize/typescript/configuring-module-format)", required: "false", default: "dual", description: "Sets the module format to use when compiling the SDK. Options: `commonjs`, `esm`, or `dual`. Using `dual` provides optimal compatibility while enabling modern bundler optimizations." }
  ]}
  columns={[
    { key: "name", header: "Name" },
    { key: "required", header: "Required" },
    { key: "default", header: "Default Value" },
    { key: "description", header: "Description" }
  ]}
/>

<Callout title="Performance optimization" type="info">
For optimal bundle size and tree-shaking performance in modern applications, we recommend using `moduleFormat: "dual"` together with `useIndexModules: false`. This combination ensures maximum compatibility while enabling the best possible bundler optimizations.
</Callout>

## Import management

```yml
typescript:
  imports:
    option: "openapi"
    paths:
      callbacks: models/callbacks
      errors: models/errors
      operations: models/operations
      shared: models/components
      webhooks: models/webhooks
```

<Table 
  data={[
    { field: "option", required: "false", default: "\"openapi\"", description: "Defines the type of import strategy. Typically set to `\"openapi\"`, indicating that the structure is based on the OpenAPI document." },
    { field: "paths", required: "false", default: "{}", description: "Customizes where different parts of the SDK (e.g., callbacks, errors, and operations) will be imported from." }
  ]}
  columns={[
    { key: "field", header: "Field" },
    { key: "required", header: "Required" },
    { key: "default", header: "Default Value" },
    { key: "description", header: "Description" }
  ]}
/>

### Import paths

<Table 
  data={[
    { component: "callbacks", default: "models/callbacks", description: "The directory where callback models will be imported from." },
    { component: "errors", default: "models/errors", description: "The directory where error models will be imported from." },
    { component: "operations", default: "models/operations", description: "The directory where operation models (i.e., API endpoints) will be imported from." },
    { component: "shared", default: "models/components", description: "The directory for shared components, such as reusable schemas, and data models imported from the OpenAPI spec." },
    { component: "webhooks", default: "models/webhooks", description: "The directory for webhook models, if the SDK includes support for webhooks." }
  ]}
  columns={[
    { key: "component", header: "Component" },
    { key: "default", header: "Default Value" },
    { key: "description", header: "Description" }
  ]}
/>


## Error and response handling

```yml
typescript:
  clientServerStatusCodesAsErrors: true
  responseFormat: "flat"
  enumFormat: "union"
  defaultErrorName: "SDKError"
  baseErrorName: "HTTPError"
  acceptHeaderEnum: false
```

<Table
  data={[
    { property: "[responseFormat](/docs/sdks/customize/responses/responses)", description: "Defines how responses are structured. Options: `envelope`, `envelope-http`, or `flat`.", type: "string", default: "flat" },
    { property: "enumFormat", description: "Determines how enums are generated. Options: `enum` (TypeScript enums) or `union` (union types).", type: "string", default: "union" },
    { property: "clientServerStatusCodesAsErrors", description: "Treats `4XX` and `5XX` status codes as errors. Set to `false` to treat them as normal responses.", type: "boolean", default: "true" },
    { property: "defaultErrorName", description: "The name of the fallback error class if no more specific error class is matched. Must start with a capital letter and contain only letters and numbers.", type: "string", default: "SDKError" },
    { property: "baseErrorName", description: "The name of the base error class used for HTTP error responses. Must start with a capital letter and contain only letters and numbers.", type: "string", default: "HTTPError" },
    { property: "acceptHeaderEnum", description: "Whether to generate TypeScript enums for controlling the return content type of SDK methods when multiple accept types are available.", type: "boolean", default: "false" }
  ]}
  columns={[
    { key: "property", header: "Property" },
    { key: "description", header: "Description" },
    { key: "type", header: "Type" },
    { key: "default", header: "Default" }
  ]}
/>

## Model validation and serialization

```yml
typescript:
  jsonpath: "rfc9535"
  zodVersion: "v4-mini"
  constFieldsAlwaysOptional: false
  modelPropertyCasing: "camel"
  unionStrategy: "populated-fields"
  laxMode: "lax"
  alwaysIncludeInboundAndOutbound: false
  exportZodModelNamespace: false
```

<Table 
  data={[
    { property: "jsonpath", description: "Sets the JSONPath implementation to use. Options: `legacy` (deprecated) or `rfc9535` (recommended). The `rfc9535` option follows the JSONPath specification and should be preferred for new SDKs.", type: "string", default: "rfc9535" },
    { property: "zodVersion", description: "The version of Zod to use for schema validation. Options: `v3`, `v4`, or `v4-mini`.", type: "string", default: "v4-mini" },
    { property: "constFieldsAlwaysOptional", description: "Whether const fields should be treated as optional in TypeScript types and schemas regardless of OpenAPI spec requirements. When `true` (legacy behavior), all const fields are optional. When `false` (recommended), const fields respect the OpenAPI spec's required array.", type: "boolean", default: "false" },
    { property: "[modelPropertyCasing](/docs/sdks/customize/typescript/property-naming)", description: "Property naming convention to use. Options: `camel` (converts to camelCase) or `snake` (converts to snake_case).", type: "string", default: "camel" },
    { property: "unionStrategy", description: "Strategy for deserializing union types. Options: `left-to-right` (tries each type in order and returns the first valid match) or `populated-fields` (tries all types and returns the one with the most matching fields, including optional fields).", type: "string", default: "populated-fields" },
    { property: "laxMode", description: "Controls validation strictness. When set to `lax`, required fields will be coerced to their zero value (e.g., a missing required string will fallback to `\"\"`). Lax mode also applies other coercions (e.g., boolean schemas will accept the string `\"true\"`). Lax mode only applies to deserialization of responses. When `laxMode` is enabled, `unionStrategy` is automatically set to `populated-fields`. Options: `lax` or `strict`.", type: "string", default: "lax" },
    { property: "alwaysIncludeInboundAndOutbound", description: "Whether to always include both inbound and outbound schemas for all types regardless of usage.", type: "boolean", default: "false" },
    { property: "exportZodModelNamespace", description: "Whether to export the deprecated `$` namespace containing `inboundSchema` and `outboundSchema` aliases.", type: "boolean", default: "false" }
  ]}
  columns={[
    { key: "property", header: "Property" },
    { key: "description", header: "Description" },
    { key: "type", header: "Type" },
    { key: "default", header: "Default" }
  ]}
/>

## Forward compatibility

These options control how the SDK handles API evolution, allowing older SDK versions to continue working when APIs add new enum values, union types, or fields.

```yml
typescript:
  forwardCompatibleEnumsByDefault: true
  forwardCompatibleUnionsByDefault: tagged-only
```

<Table 
  data={[
    { property: "forwardCompatibleEnumsByDefault", description: "Controls whether enums used in responses are treated as open enums that accept unknown values. When `true`, SDKs gracefully handle new enum values added by the API instead of rejecting the response. Individual enums can be controlled with `x-speakeasy-unknown-values: allow` or `x-speakeasy-unknown-values: disallow` in the OpenAPI spec.", type: "boolean", default: "true" },
    { property: "forwardCompatibleUnionsByDefault", description: "Controls whether discriminated unions accept unknown discriminator values. When set to `tagged-only`, SDKs capture unknown union variants in a type-safe way instead of failing deserialization. Individual unions can be controlled with `x-speakeasy-unknown-values: allow` or `x-speakeasy-unknown-values: disallow` in the OpenAPI spec.", type: "string", default: "tagged-only" }
  ]}
  columns={[
    { key: "property", header: "Property" },
    { key: "description", header: "Description" },
    { key: "type", header: "Type" },
    { key: "default", header: "Default" }
  ]}
/>

<Callout title="Forward compatibility and fault tolerance" type="info">
These options work together with `laxMode` and `unionStrategy` to provide robust forward compatibility. When all four features are enabled (the default for new TypeScript SDKs), your SDK will gracefully handle API evolution including new enum values, new union types, missing fields, and type mismatches. See the [forward compatibility guide](/docs/sdks/manage/forward-compatibility) for more details.
</Callout>

## Server-sent events configuration

```yml
typescript:
  sseFlatResponse: false
```

<Table 
  data={[
    { property: "[sseFlatResponse](/docs/sdks/customize/runtime/server-sent-events)", description: "Whether to flatten SSE (Server-Sent Events) responses by extracting the `data` field from wrapper models, providing direct access to the event data instead of the wrapper object.", type: "boolean", default: "false" }
  ]}
  columns={[
    { key: "property", header: "Property" },
    { key: "description", header: "Description" },
    { key: "type", header: "Type" },
    { key: "default", header: "Default" }
  ]}
/>

## Advanced features

```yml
typescript:
  enableReactQuery: false
```

<Table 
  data={[
    { property: "[enableReactQuery](/docs/sdks/customize/typescript/react-hooks)", description: "Generate React hooks using TanStack Query.", type: "boolean", default: "false" }
  ]}
  columns={[
    { key: "property", header: "Property" },
    { key: "description", header: "Description" },
    { key: "type", header: "Type" },
    { key: "default", header: "Default" }
  ]}
/>