Output
You must set the output so we know where to generate your files.
Output
Output can be a path to the destination folder or an object containing the destination folder path and optional settings.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: 'src/client',
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
// ...other options
},
};You can learn more about complex use cases in the Advanced section.
File
Control how files are named and annotated in the generated output.
File Name
You can customize the naming and casing pattern for files using the fileName option.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: '{{name}}',
path: 'src/client',
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: {
case: 'snake_case',
},
path: 'src/client',
},
};By default, we append every file name with a .gen suffix to highlight it's automatically generated. You can customize or disable this suffix using the fileName.suffix option.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: {
suffix: '.gen',
},
path: 'src/client',
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: {
suffix: null,
},
path: 'src/client',
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
fileName: {
suffix: '.generated',
},
path: 'src/client',
},
};File Header
The generated output includes a notice in every file warning that any modifications will be lost when the files are regenerated. You can customize or disable this notice using the header option.
/* eslint-disable */
// This file is auto-generated by @hey-api/openapi-ts
/** ... */export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
header: (ctx) => [
'/* eslint-disable */',
...ctx.defaultValue,
],
path: 'src/client',
},
};Module
Control how module specifiers are generated in the output.
Module Extension
Set module.extension to define the file extension used in import specifiers. This is useful when targeting environments that require fully specified imports (e.g., Node ESM or certain bundlers).
import foo from './foo.js';
import bar from './bar.js';export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
module: {
extension: '.js',
},
path: 'src/client',
},
};Module Path
Use module.resolve for full control over how module specifiers are generated. This lets you override specific modules or redirect them to custom locations (e.g., CDNs or internal aliases).
import * as z from 'https://esm.sh/zod';export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
module: {
resolve(path) {
if (path === 'zod') {
return 'https://esm.sh/zod';
}
},
},
path: 'src/client',
},
};Source
Source is a copy of the input specification used to generate your output. It can be used to power documentation tools or to persist a stable snapshot alongside your generated files.
Enabling the source option with true creates a source.json file in your output folder.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
source: true,
},
};You can customize the file name and location using fileName and path. For example, this configuration will create an openapi.json file inside src/client/source directory.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
source: {
fileName: 'openapi',
path: './source',
},
},
};To use the source without writing it to disk, you can provide a callback function. This is useful for logging or integrating with external systems.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
source: {
callback: (source) => console.log(source),
path: null,
},
},
};Post Process
Post-processing allows you to run commands on the generated output folder after files are written. This is typically used to run formatters, linters, or other cleanup tools.
Commands are executed in order, and each command receives the output path via the path placeholder.
Presets
You can use built-in presets for common tools:
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['biome:format'],
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['biome:lint'],
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['eslint'],
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['oxfmt'],
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['oxlint'],
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: ['prettier'],
},
};Custom
You can also provide custom post processors:
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
postProcess: [{
command: 'dprint',
args: ['fmt', '{{path}}'],
}],
},
};You can skip processing by adding the output path to the tool's ignore file (for example .eslintignore or .prettierignore).
Name Conflicts
As your project grows, the chances of name conflicts increase. We use a simple conflict resolver that appends numeric suffixes to duplicate identifiers. If you prefer a different strategy, you can provide your own nameConflictResolver function.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
nameConflictResolver({ attempt, baseName }) {
return attempt === 0 ? baseName : `${baseName}_N${attempt + 1}`;
},
path: 'src/client',
},
};export type ChatCompletion = string;
export type ChatCompletion_N2 = number;TSConfig Path
We use the TSConfig file to generate output matching your project's settings. By default, we attempt to find a TSConfig file starting from the location of the @hey-api/openapi-ts configuration file and traversing up.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
tsConfigPath: undefined,
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
tsConfigPath: './config/tsconfig.custom.json',
},
};export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
path: 'src/client',
tsConfigPath: null,
},
};Custom Files
By default, you can't keep custom files in the path folder because it's emptied on every run. If you're sure you need to disable this behavior, set clean to false.
export default {
input: 'hey-api/backend', // sign up at app.heyapi.dev
output: {
clean: false,
path: 'src/client',
},
};WARNING
Setting clean to false may result in broken output. Ensure you typecheck your code.
Examples
You can view live examples on StackBlitz.
Sponsors
Hey API is sponsor-funded. If you rely on Hey API in production, consider becoming a sponsor to accelerate the roadmap.
Gold

Best-in-class developer interfaces for your API.
stainless.comThe open source coding agent.
opencode.aiThe intelligent knowledge platform.
mintlify.com
