Migrating
While we try to avoid breaking changes, sometimes it's unavoidable in order to offer you the latest features. This page lists changes that require updates to your code. If you run into a problem with migration, pleaseopen an issue.
v0.93.0
Removed resolver node
Valibot and Zod plugins no longer expose theenum.nodes.nullable node. Both plugins were refactored so that nullable values are handled outside of resolvers.
v0.92.0
Updated Symbol interface
TheexportFrom property has been replaced with thegetExportFromFilePath() function. This allows you to dynamically determine export paths based on symbol properties. This is a low-level feature, so you're most likely unaffected.
v0.91.0
Removed CommonJS (CJS) support
@hey-api/openapi-ts is now ESM-only. This change simplifies the codebase, improves tree-shaking, and enables better integration with modern bundlers and TypeScript tooling.
CommonJS entry points (require(),module.exports) are no longer supported. If you are in a CJS environment, you can still load the package dynamically usingimport() like:
const {defineConfig }= await import('@hey-api/openapi-ts');If you have previously written:
const {defineConfig }= require('@hey-api/openapi-ts');Migrate by updating your static imports:
import { defineConfig }from '@hey-api/openapi-ts';If your environment cannot use ESM, pin to a previous version.
v0.90.0
Resolvers API
TheResolvers API has been simplified and expanded to provide a more consistent behavior across plugins. You can view a few common examples on theResolvers page.
Structure API
TheSDK plugin andAngular plugin now implement the Structure API, enabling more complex structures and fixing several known issues.
Some Structure APIs are incompatible with the previous configuration, most notably themethodNameBuilder function, which accepted the operation object as an argument. You can read theSDK Output section to familiarize yourself with the Structure API.
Pleaseopen an issue if you're unable to migrate your configuration to the new syntax.
v0.89.0
Prefer named exports
This release changes the default forindex.ts to prefer named exports. Named exports may lead to better IDE and bundler performance compared to asterisk (*) as your tooling doesn't have to inspect the underlying module to discover exports.
While this change is merely cosmetic, you can setoutput.preferExportAll totrue if you prefer to use the asterisk.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output: { path:'src/client', preferExportAll:true, },};Removedsymbol:setValue:* events
These events have been removed in favor ofnode:set:* events.
v0.88.0
Removedcompiler andtsc exports
This release removes thecompiler utility functions. Instead, it introduces a new TypeScript DSL exposed under the$ symbol. All plugins now use this interface, so you may notice slight changes in the generated output.
v0.87.0
Removed legacy clients
This release removes support for legacy clients and plugins. Please migrate to the new clients if you haven't done so yet. If you're unable to do so due to a missing feature, let us know onGitHub.
v0.86.0
Removed Node 18 support
This release bumps the minimum required Node version to 20.19.
v0.85.0
Updatedoutput options
We made theoutput configuration more consistent by usingnull to represent disabled options. This change does not affect boolean options.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output: { format:false, format:null, lint:false, lint:null, path:'src/client', tsConfigPath:'off', tsConfigPath:null, },};Updated Pinia Colada query options
Pinia Colada query options now usedefineQueryOptions to improve reactivity support. Instead of calling the query options function, you can use one of the following approaches.
useQuery(getPetsQuery);useQuery(getPetByIdQuery, ()=> ({ path: { petId:1, },}));const petId = ref<number | null>(1);useQuery(getPetByIdQuery, ()=> ({ path: { petId: petId.value, },}));const petId = ref<number | null>(1);useQuery(()=> ({ ...getPetByIdQuery({ path: { petId: petId.valueas number }, }), enabled: ()=> petId.value!= null,}));v0.84.0
Symbol API
This release improves the Symbol API, which adds the capability to place symbols in arbitrary files. We preserved the previous output structure for all plugins except Angular.
You can preserve the previous Angular output by writing your ownplacement function.
TypeScript renderer
We ship a dedicated TypeScript renderer for.ts files. This release improves the renderer's ability to group and sort imported modules, resulting in a more polished output.
Removedoutput plugin option
Due to the Symbol API release, this option has been removed from the Plugin API.
v0.83.0
Symbol API
This release adds the Symbol API, which significantly reduces the risk of naming collisions. While the generated output should only include formatting changes, this feature introduces breaking changes to the Plugin API that affect custom plugins.
We will update thecustom plugin guide once the Plugin API becomes more stable.
RemovedgroupByTag Pinia Colada option
This option has been removed to provide a more consistent API across plugins. We plan to bring it back in a future release.
v0.82.0
Hooks API
This release adds theHooks API, giving you granular control over which operations generate queries and mutations. As a result, we tightened the previous behavior and POST operations no longer generate queries by default. To preserve the old behavior, add a custom matcher.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', parser: { hooks: { operations: { isQuery: (op)=> (op.method=== 'post' ? true : undefined), }, }, },};v0.81.0
Server-Sent Events (SSE)
This release adds support for server-sent events (SSE). Instead of treatingtext/event-stream content types as regular HTTP methods, we now generate SSE streams. In practice, you will want to update your affected endpoints to process streamed events.
const {data }= await foo();console.log(data.type);const {stream }= await foo();for await (const event of stream) { console.log(event.type);}v0.80.0
Added Zod 4 and Zod Mini
This release adds support for Zod 4 and Zod Mini. By default, thezod plugin will generate output for Zod 4. If you want to preserve the previous output for Zod 3 or use Zod Mini, setcompatibilityVersion to3 ormini.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { name:'zod', compatibilityVersion:3, }, ],};export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { name:'zod', compatibilityVersion:'mini', }, ],};v0.79.0
Removedtypescript+namespace enums mode
Due to a simpler TypeScript plugin implementation, thetypescript+namespace enums mode is no longer necessary. This mode was used in the past to group inline enums under the same namespace. With the latest changes, this behavior is no longer supported. You can either choose to ignore inline enums (default), or use theenums transform (added in v0.78.0) to convert them into reusable components which will get exported as usual.
v0.78.0
Addedparser options
Previously,@hey-api/typescript would generate correct types, but the validator plugins would have to re-implement the same logic or generate schemas that didn't match the generated types.
Since neither option was ideal, this release adds a dedicated place forparser options. Parser is responsible for preparing the input so plugins can generate more accurate output with less effort.
You can learn more about configuring parser on theParser page.
Movedinput options
The following options were moved to the newparser group.
input.filtersmoved toparser.filtersinput.paginationmoved toparser.paginationinput.patchmoved toparser.patchinput.validate_EXPERIMENTALmoved toparser.validate_EXPERIMENTAL
Updatedtypescript options
The following options were renamed.
enumsCasemoved toenums.caseenumsConstantsIgnoreNullmoved toenums.constantsIgnoreNull
Movedtypescript options
The following options were moved to the newparser group.
exportInlineEnumsmoved toparser.transforms.enumsreadOnlyWriteOnlyBehaviormoved toparser.transforms.readWrite.enabledreadableNameBuildermoved toparser.transforms.readWrite.responses.namewritableNameBuildermoved toparser.transforms.readWrite.requests.name
UpdatedreadWrite.responses name
Additionally, the naming pattern for response schemas has changed from{name}Readable to{name}. This is to prevent your code from breaking by default when using a schema that gets updated with a write-only field.
v0.77.0
Updatedsdk.validator option
Clients can now validate both request and response data. As a result, passing a boolean or string tovalidator will control both of these options. To preserve the previous behavior, setvalidator.request tofalse andvalidator.response to your previous configuration.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { name:'@hey-api/sdk', validator:true, validator: { request:false, response:true, }, }, ],};Updated Plugin API
Please refer to thecustom plugin tutorial for the latest guide.
v0.76.0
Single Valibot schema per request
Previously, we generated a separate schema for each endpoint parameter and request body. In v0.76.0, a single request schema is generated for the whole endpoint. It may contain a request body, parameters, and headers.
const vData = v.object({ body: v.optional( v.object({ foo: v.optional(v.string()), bar: v.optional(v.union([v.number(), v.null()])), }), ), headers: v.optional(v.never()), path: v.object({ baz: v.string(), }), query: v.optional(v.never()),});If you need to access individual fields, you can do so using the.entries API. For example, we can get the request body schema withvData.entries.body.
v0.75.0
Updated TanStack Query options
The TanStack Query plugin options have been expanded to support more naming and casing patterns. As a result, the following options have been renamed.
queryOptionsNameBuilderrenamed toqueryOptionsinfiniteQueryOptionsNameBuilderrenamed toinfiniteQueryOptionsmutationOptionsNameBuilderrenamed tomutationOptionsqueryKeyNameBuilderrenamed toqueryKeysinfiniteQueryKeyNameBuilderrenamed toinfiniteQueryKeys
Addedplugin.forEach() method
This method replaces the.subscribe() method. Additionally,.forEach() is executed immediately, which means we don't need thebefore andafter events – simply move your code before and after the.forEach() block.
plugin.subscribe('operation', (event)=> { // do something with event});plugin.subscribe('schema', (event)=> {plugin.forEach('operation','schema', (event)=> { // do something with event});v0.74.0
Single Zod schema per request
Previously, we generated a separate schema for each endpoint parameter and request body. In v0.74.0, a single request schema is generated for the whole endpoint. It may contain a request body, parameters, and headers.
const zData = z.object({ body: z .object({ foo: z.string().optional(), bar: z.union([z.number(), z.null()]).optional(), }) .optional(), headers: z.never().optional(), path: z.object({ baz: z.string(), }), query: z.never().optional(),});If you need to access individual fields, you can do so using the.shape API. For example, we can get the request body schema withzData.shape.body.
v0.73.0
Bundle@hey-api/client-* plugins
In previous releases, you had to install a separate client package to generate a fully working output, e.g.npm install @hey-api/client-fetch. This created a few challenges: getting started was slower, upgrading was sometimes painful, and bundling too. Beginning with v0.73.0, all Hey API clients are bundled by default and don't require installing any additional dependencies. You can remove any installed client packages and re-run@hey-api/openapi-ts.
npm uninstall @hey-api/client-fetchv0.72.0
Addedsdk.classStructure option
When generating class-based SDKs, we now try to infer the ideal structure usingoperationId keywords. If you'd like to preserve the previous behavior, setclassStructure tooff.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { classStructure:'off', name:'@hey-api/sdk', }, ],};v0.71.0
Renamedsdk.serviceNameBuilder option
This option has been renamed tosdk.classNameBuilder to better represent its functionality. Additionally, it's no longer set by default. To preserve the previous behavior, update your configuration.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { classNameBuilder:'{{name}}Service', name:'@hey-api/sdk', serviceNameBuilder:'{{name}}Service', }, ],};v0.68.0
Upgraded input filters
Input filters now avoid generating invalid output without requiring you to specify every missing schema as in the previous releases. As part of this release, we changed the way filters are configured and removed the support for regular expressions. Let us know if regular expressions are still useful for you and want to bring them back!
export default { input: { // match only the schema named `foo` and `GET` operation for the `/api/v1/foo` path filters: { operations: { include: ['GET /api/v1/foo'], }, schemas: { include: ['foo'], }, }, include:'^(#/components/schemas/foo|#/paths/api/v1/foo/get)$', path:'hey-api/backend',// sign up at app.heyapi.dev }, output:'src/client', plugins: ['@hey-api/client-fetch'],};export default { input: { // match everything except for the schema named `foo` and `GET` operation for the `/api/v1/foo` path exclude:'^(#/components/schemas/foo|#/paths/api/v1/foo/get)$', filters: { operations: { exclude: ['GET /api/v1/foo'], }, schemas: { exclude: ['foo'], }, }, path:'hey-api/backend',// sign up at app.heyapi.dev }, output:'src/client', plugins: ['@hey-api/client-fetch'],};v0.67.0
RespectingmoduleResolution value intsconfig.json
This release introduces functionality related to yourtsconfig.json file. The initial feature properly respects the value of yourmoduleResolution field. If you're usingnodenext, the relative module paths in your output will be appended with.js. To preserve the previous behavior where we never appended.js to relative module paths, setoutput.tsConfigPath tooff.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output: { path:'src/client', tsConfigPath:'off', },};v0.66.0
Read-only and write-only fields
Starting with v0.66.0,@hey-api/typescript will generate separate types for payloads and responses if it detects any read-only or write-only fields. To preserve the previous behavior and generate a single type regardless, setreadOnlyWriteOnlyBehavior tooff.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { name:'@hey-api/typescript', readOnlyWriteOnlyBehavior:'off', }, ],};v0.64.0
AddedClientOptions interface
TheConfig interface now accepts an optional generic extendingClientOptions instead ofboolean typeThrowOnError.
type Foo = Config<false>;type Foo = Config<{throwOnError: false }>;Addedclient.baseUrl option
You can use this option to configure the default base URL for the generated client. By default, we will attempt to resolve the first defined server or infer the base URL from the input path. If you'd like to preserve the previous behavior, setbaseUrl tofalse.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ { baseUrl:false, name:'@hey-api/client-fetch', }, ],};v0.63.0
Client plugins
Clients are now plugins generating their ownclient.gen.ts file. There's no migration needed if you're using CLI. If you're using the configuration file, moveclient options toplugins.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: ['@hey-api/client-fetch'],};Addedclient.gen.ts file
Related to above, the internalclient instance previously located insdk.gen.ts is now defined inclient.gen.ts. If you're importing it in your code, update the import module.
import { client }from 'client/sdk.gen';import { client }from 'client/client.gen';Movedsdk.throwOnError option
This SDK configuration option has been moved to the client plugins where applicable. Not every client can be configured to throw on error, so it didn't make sense to expose the option when it didn't have any effect.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ { name:'@hey-api/client-fetch', throwOnError:true, }, { name:'@hey-api/sdk', throwOnError:true, }, ],};v0.62.0
Changed parser
Formerly known as the experimental parser, this is now the default parser. This change should not impact the generated output's functionality. However, there might be cases where this results in breaking changes due to different handling of certain scenarios. If you need to revert to the legacy parser, set theexperimentalParser flag tofalse.
export default { client:'@hey-api/client-fetch', experimentalParser:false, input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',};Note that the legacy parser is no longer supported and will be removed in the v1 release.
v0.61.0
Addedauth option
Client package functionsaccessToken andapiKey were replaced with a singleauth function for fetching auth tokens. If your API supports multiple auth mechanisms, you can use theauth argument to return the appropriate token.
import { client }from 'client/sdk.gen';client.setConfig({ accessToken: ()=> '<my_token>', apiKey: ()=> '<my_token>', auth: (auth)=> '<my_token>',});Due to conflict with the Axios nativeauth option, we removed support for configuring Axios auth. Please let us know if you require this feature added back.
Addedwatch option
While this is a new feature, supporting it involved replacing the@apidevtools/json-schema-ref-parser dependency with our own implementation. Since this was a big change, we're applying caution and marking this as a breaking change.
ChangedparseAs: 'auto' behavior
The Fetch API client will return raw response body asReadableStream whenContent-Type response header is undefined andparseAs isauto.
v0.60.0
Addedsdk.transformer option
When generating SDKs, you now have to specifytransformer in order to modify response data. By default, adding@hey-api/transformers to your plugins will only produce additional output. To preserve the previous functionality, setsdk.transformer totrue.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { dates:true, name:'@hey-api/transformers', }, { name:'@hey-api/sdk', transformer:true, }, ],};v0.59.0
Addedlogs.level option
You can now configure different log levels. As part of this feature, we had to introduce a breaking change by moving thedebug option tologs.level. This will affect you if you're calling@hey-api/openapi-ts from Node.js (not CLI) or using the configuration file.
export default { client:'@hey-api/client-fetch', debug:true, input:'hey-api/backend',// sign up at app.heyapi.dev logs: { level:'debug', }, output:'src/client',};Updated defaultplugins
@hey-api/schemas has been removed from the default plugins. To continue using it, add it to your plugins array.
export default { client:'@hey-api/client-fetch', experimentalParser:true, input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins '@hey-api/schemas', ],};v0.58.0
Removedschemas.gen.ts re-export
index.ts will no longer re-exportschemas.gen.ts to reduce the chance of producing broken output. Please update your code to import fromschemas.gen.ts directly.
import { mySchema }from 'client';import { mySchema }from 'client/schemas.gen';Removedtransformers.gen.ts re-export
index.ts will no longer re-exporttransformers.gen.ts to reduce the chance of producing broken output. Please update your code to import fromtransformers.gen.ts directly.
import { myTransformer }from 'client';import { myTransformer }from 'client/transformers.gen';Addedoutput.clean option
By default, theoutput.path folder will be emptied on every run. To preserve the previous behavior, setoutput.clean tofalse.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output: { clean:false, path:'src/client', },};Addedtypescript.identifierCase option
This change affects only the experimental parser. By default, the generated TypeScript interfaces will follow the PascalCase naming convention. In the previous versions, we tried to preserve the original name as much as possible. To keep the previous behavior, settypescript.identifierCase topreserve.
export default { client:'@hey-api/client-fetch', experimentalParser:true, input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { identifierCase:'preserve', name:'@hey-api/typescript', }, ],};v0.57.0
Renamed@hey-api/services plugin
This plugin has been renamed to@hey-api/sdk.
Changedsdk.output value
To align with the updated name, the@hey-api/sdk plugin will generate ansdk.gen.ts file. This will result in a breaking change if you're importing fromservices.gen.ts. Please update your imports to reflect this change.
import { client }from 'client/services.gen';import { client }from 'client/sdk.gen';Renamed@hey-api/types plugin
This plugin has been renamed to@hey-api/typescript.
Addedtypescript.exportInlineEnums option
By default, inline enums (enums not defined as reusable components in the input file) will be generated only as inlined union types. You can setexportInlineEnums totrue to treat inline enums as reusable components. Whentrue, the exported enums will follow the style defined inenums.
This is a breaking change since in the previous versions, inline enums were always treated as reusable components. To preserve your current output, setexportInlineEnums totrue. This feature works only with the experimental parser.
export default { client:'@hey-api/client-fetch', experimentalParser:true, input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ // ...other plugins { exportInlineEnums:true, name:'@hey-api/typescript', }, ],};v0.56.0
Deprecatedtree in@hey-api/types
This config option is deprecated and will be removed when the experimental parser becomes the default.
v0.55.0
This release adds the ability to filter your OpenAPI specification before it's processed. This feature will be useful if you are working with a large specification and are interested in generating output only from a small subset.
This feature is available only in the experimental parser. In the future, this will become the default parser. To opt-in to the experimental parser, set theexperimentalParser flag in your configuration totrue.
Deprecatedinclude in@hey-api/types
This config option is deprecated and will be removed when the experimental parser becomes the default.
Deprecatedfilter in@hey-api/services
This config option is deprecated and will be removed when the experimental parser becomes the default.
Addedinput.include option
This config option can be used to replace the deprecated options. It accepts a regular expression string matching against references within the bundled specification.
export default { client:'@hey-api/client-fetch', experimentalParser:true, input: { include:'^(#/components/schemas/foo|#/paths/api/v1/foo/get)$', path:'hey-api/backend',// sign up at app.heyapi.dev }, output:'src/client',};The configuration above will process only the schema namedfoo andGET operation for the/api/v1/foo path.
v0.54.0
This release makes plugins first-class citizens. In order to achieve that, the following breaking changes were introduced.
Removed CLI options
The--types,--schemas, and--services CLI options have been removed. You can list which plugins you'd like to use explicitly by passing a list of plugins as--plugins <plugin1> <plugin2>
Removed*.export option
Previously, you could explicitly disable export of certain artifacts using the*.export option or its shorthand variant. These were both removed. You can now disable export of specific artifacts by manually defining an array ofplugins and excluding the unwanted plugin.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', schemas:false, plugins: ['@hey-api/types','@hey-api/services'],};export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', schemas: { export:false, }, plugins: ['@hey-api/types','@hey-api/services'],};Renamedschemas.name option
Each plugin definition contains aname field. This was conflicting with theschemas.name option. As a result, it has been renamed tonameBuilder.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', schemas: { name: (name)=> `${name}Schema`, }, plugins: [ // ...other plugins { nameBuilder: (name)=> `${name}Schema`, name:'@hey-api/schemas', }, ],};Removedservices.include shorthand option
Previously, you could use a string value as a shorthand for theservices.include configuration option. You can now achieve the same result using theinclude option.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', services:'^MySchema', plugins: [ // ...other plugins { include:'^MySchema', name:'@hey-api/services', }, ],};Renamedservices.name option
Each plugin definition contains aname field. This was conflicting with theservices.name option. As a result, it has been renamed toserviceNameBuilder.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', services: { name:'{{name}}Service', }, plugins: [ // ...other plugins { serviceNameBuilder:'{{name}}Service', name:'@hey-api/services', }, ],};Renamedtypes.dates option
Previously, you could settypes.dates to a boolean or a string value, depending on whether you wanted to transform only type strings into dates, or runtime code too. Many people found these options confusing, so they have been simplified to a boolean and extracted into a separate@hey-api/transformers plugin.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', types: { dates:'types+transform', }, plugins: [ // ...other plugins { dates:true, name:'@hey-api/transformers', }, ],};Removedtypes.include shorthand option
Previously, you could use a string value as a shorthand for thetypes.include configuration option. You can now achieve the same result using theinclude option.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', types:'^MySchema', plugins: [ // ...other plugins { include:'^MySchema', name:'@hey-api/types', }, ],};Renamedtypes.name option
Each plugin definition contains aname field. This was conflicting with thetypes.name option. As a result, it has been renamed tostyle.
export default { client:'@hey-api/client-fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', types: { name:'PascalCase', }, plugins: [ // ...other plugins { name:'@hey-api/types', style:'PascalCase', }, ],};v0.53.0
Changed schemas name pattern
Previously, generated schemas would have their definition names prefixed with$. This was problematic when using them with Svelte due to reserved keyword conflicts. The new naming pattern for schemas suffixes their definition names withSchema. You can continue using the previous pattern by setting theschemas.name configuration option.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', schemas: { name: (name)=> `$${name}`, },};Renamed legacy clients
Legacy clients were renamed to signal they are deprecated more clearly. To continue using legacy clients, you will need to update your configuration and prefix them withlegacy/.
export default { client:'fetch', client:'legacy/fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',};export default { client:'axios', client:'legacy/axios', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',};export default { client:'angular', client:'legacy/angular', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',};export default { client:'node', client:'legacy/node', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',};export default { client:'xhr', client:'legacy/xhr', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',};v0.52.0
Removed internalclient export
Previously, client packages would create a default client which you'd then import and configure.
import { client, createClient }from '@hey-api/client-fetch';createClient({ baseUrl:'https://example.com',});console.log(client.getConfig().baseUrl);// <-- 'https://example.com'This client instance was used internally by services unless overridden. Apart from runningcreateClient() twice, people were confused about the meaning ofglobal configuration option.
Starting with v0.52.0, client packages will not create a default client. Instead, services will define their own client. You can now achieve the same configuration by importingclient from services and using the newsetConfig() method.
import { client }from 'client/services.gen';client.setConfig({ baseUrl:'https://example.com',});console.log(client.getConfig().baseUrl);// <-- 'https://example.com'v0.51.0
Requiredclient option
Client now has to be explicitly specified and@hey-api/openapi-ts will no longer generate a legacy Fetch API client by default. To preserve the previous default behavior, set theclient option tofetch.
export default { client:'fetch', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',};v0.48.0
ChangedmethodNameBuilder() signature
Theservices.methodNameBuilder() function now provides a singleoperation argument instead of multiple cherry-picked properties from it.
import { createClient }from '@hey-api/openapi-ts';createClient({ input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', services: { methodNameBuilder: (service,name)=> name, methodNameBuilder: (operation)=> operation.name, },});v0.46.0
Tree-shakeable services
By default, your services will now supporttree-shaking. You can either use wildcard imports
import { DefaultService }from 'client/services.gen';import * as DefaultServicefrom 'client/services.gen';DefaultService.foo();// only import needs to be changedor update all references to service classes
import { DefaultService }from 'client/services.gen';import { foo }from 'client/services.gen';foo();// all references need to be changedIf you want to preserve the old behavior, you can set the newly exposedservices.asClass option totrue.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', services: { asClass:true, },};v0.45.0
Removedclient inference
@hey-api/openapi-ts will no longer infer which client you want to generate. By default, we will create afetch client. If you want a different client, you can specify it using theclient option.
export default { client:'axios', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',};v0.44.0
Movedformat
This config option has been moved. You can now configure formatter using theoutput.format option.
export default { format:'prettier', input:'hey-api/backend',// sign up at app.heyapi.dev output: { format:'prettier', path:'src/client', },};Movedlint
This config option has been moved. You can now configure linter using theoutput.lint option.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev lint:'eslint', output: { lint:'eslint', path:'src/client', },};v0.43.0
Removedenums.gen.ts
This file has been removed. Instead, enums are exported fromtypes.gen.ts. If you use imports fromenums.gen.ts, you should be able to easily find and replace all instances.
import { Foo }from 'client/enums.gen';import { Foo }from 'client/types.gen';RemovedEnum postfix
Generated enum names are no longer postfixed withEnum. You can either alias your imports
import { FooEnum }from 'client/types.gen';import { Fooas FooEnum }from 'client/types.gen';console.log(FooEnum.value);// only import needs to be changedor update all references to enums
import { FooEnum }from 'client/types.gen';import { Foo }from 'client/types.gen';console.log(Foo.value);// all references need to be changedMovedenums
This config option has been moved. You can now configure enums using thetypes.enums option.
export default { enums:'javascript', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', types: { enums:'javascript', },};v0.42.0
Changedformat
This config option has changed. You now need to specify a value (biome orprettier) to format the output (default:false).
export default { format:'prettier', input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client',}Changedlint
This config option has changed. You now need to specify a value (biome oreslint) to lint the output (default:false).
export default { input:'hey-api/backend',// sign up at app.heyapi.dev lint:'eslint', output:'src/client',}MovedoperationId
This config option has been moved. You can now configure it using theservices.operationId option.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', services: { operationId:true, },}v0.41.0
RemovedpostfixServices
This config option has been removed. You can now transform service names using the string pattern parameter.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', services: { name:'myAwesome{{name}}Api', },}RemovedserviceResponse
This config option has been removed. You can now configure service responses using theservices.response option.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', services: { response:'body', },}RemoveduseDateType
This config option has been removed. You can now configure date type using thetypes.dates option.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', type: { dates:true, },}v0.40.0
Renamedmodels.gen.ts file
models.gen.ts is now calledtypes.gen.ts. If you use imports frommodels.gen.ts, you should be able to easily find and replace all instances.
import type { Model }from 'client/models.gen'import type { Model }from 'client/types.gen'RenamedexportModels
This config option is now calledtypes.
PascalCase for types
You can now choose to export types using the PascalCase naming convention.
export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', types: { name:'PascalCase', },}Exportedenums.gen.ts file
Enums are now re-exported from the mainindex.ts file.
v0.39.0
Singleenums.gen.ts file
Enums are now exported from a separate file. If you use imports frommodels.ts, you can change them toenums.gen.ts.
import { Enum }from 'client/models';import { Enum }from 'client/enums.gen';Renamedmodels.ts file
models.ts is now calledmodels.gen.ts. If you use imports frommodels.ts, you should be able to easily find and replace all instances.
import type { Model }from 'client/models'import type { Model }from 'client/models.gen'Renamedschemas.ts file
schemas.ts is now calledschemas.gen.ts. If you use imports fromschemas.ts, you should be able to easily find and replace all instances.
import { $Schema }from 'client/schemas';import { $Schema }from 'client/schemas.gen';Renamedservices.ts file
services.ts is now calledservices.gen.ts. If you use imports fromservices.ts, you should be able to easily find and replace all instances.
import { DefaultService }from 'client/services';import { DefaultService }from 'client/services.gen';Deprecated exports fromindex.ts
Until this release,index.ts file exported all generated artifacts. Starting from this release, enums are no longer exported fromindex.ts. Models, schemas, and services will continue to be exported fromindex.ts to avoid a huge migration lift, but we recommend migrating to import groups per artifact type.
import { Enum,type Model, $Schema, DefaultService }from 'client'import { Enum }from 'client/enums.gen'import type { Model }from 'client/models.gen'import { $Schema }from 'client/schemas.gen'import { DefaultService }from 'client/services.gen'Preferunknown
Types that cannot be determined will now be generated asunknown instead ofany. To dismiss any errors, you can cast your variables back toany, but we recommend updating your code to work withunknown types.
const foo = baras anyv0.38.0
Renamedwrite
This config option is now calleddryRun (file) or--dry-run (CLI). To restore existing functionality, invert the value, ie.write: true isdryRun: false andwrite: false isdryRun: true.
v0.36.0
JSON Schema 2020-12
Schemas are exported directly from OpenAPI specification. This means your schemas might change depending on which OpenAPI version you're using. If this release caused a field to be removed, consult the JSON Schema documentation on how to obtain the same value from JSON Schema (eg.required properties).
RenamedexportSchemas
This config option is now calledschemas.
v0.35.0
RemovedpostfixModels
This config option has been removed.
v0.34.0
Singleservices.ts file
Services are now exported from a single file. If you used imports from individual service files, these will need to be updated to refer to the singleservices.ts file.
v0.31.1
Merged enums options
useLegacyEnums config option is nowenums: 'typescript' and existingenums: true option is nowenums: 'javascript'.
v0.31.0
Singlemodels.ts file
TypeScript interfaces are now exported from a single file. If you used imports from individual model files, these will need to be updated to refer to the singlemodels.ts file.
Singleschemas.ts file
Schemas are now exported from a single file. If you used imports from individual schema files, these will need to be updated to refer to the singleschemas.ts file.
v0.27.38
useOptions: true
By default, generated clients will use a single object argument to pass values to API calls. This is a significant change from the previous default of unspecified array of arguments. If migrating your application in one go isn't feasible, we recommend deprecating your old client and generating a new client.
import { DefaultService }from 'client/services';// <-- old client with array argumentsimport { DefaultService }from 'client_v2/services';// <-- new client with options argumentThis way, you can gradually switch over to the new syntax as you update parts of your code. Once you've removed all instances ofclient imports, you can safely delete the oldclient folder and find and replace allclient_v2 calls toclient.
v0.27.36
exportSchemas: true
By default, we will create schemas from your OpenAPI specification. UseexportSchemas: false to preserve the old behavior.
v0.27.32
RenamedConfig interface
This interface is now calledUserConfig.
v0.27.29
Renamedopenapi CLI command
This command is now calledopenapi-ts.
v0.27.26
Removedindent
This config option has been removed. Use acode formatter to modify the generated files code style according to your preferences.
v0.27.24
RemoveduseUnionTypes
This config option has been removed. Generated types will behave the same asuseUnionTypes: true before.
OpenAPI TypeScript Codegen
@hey-api/openapi-ts was originally forked from Ferdi Koomen'sopenapi-typescript-codegen. Therefore, we want you to be able to migrate your projects. Migration should be relatively straightforward if you follow the release notes on this page. Start onv0.27.24 and scroll to the release you're migrating to.