Custom Plugin
WARNING
Plugin API is in development. The interface might change before it becomes stable. We encourage you to leave feedback onGitHub.
WARNING
This page is out of date as ofv0.83.0. If you have an existing custom plugin, we recommend waiting for a more stable Plugin API to avoid multiple plugin rewrites.
You may need to write your own plugin if the available plugins do not suit your needs or you're working on a proprietary use case. This can be easily achieved using the Plugin API. But don't take our word for it – all Hey API plugins are written this way!
File Structure
We recommend following the design pattern of the native plugins. You can browse the code onGitHub as you follow this tutorial. First, create amy-plugin folder for your plugin files. Inside, create a barrel fileindex.ts exporting the plugin.
export { defaultConfig, defineConfig }from './config';export type { MyPlugin }from './types';TypeScript
index.ts references two files, so we need to create them.types.ts contains the TypeScript interface for your plugin options. It must have the reservedname andoutput fields, everything else will become user-configurable options.
import type { DefinePlugin }from '@hey-api/openapi-ts';export type UserConfig = { /** * Plugin name. Must be unique. */ name: 'my-plugin'; /** * Name of the generated file. * *@default 'my-plugin' */ output?: string; /** * User-configurable option for your plugin. * *@default false */ myOption?: boolean;};export type MyPlugin = DefinePlugin<UserConfig>;Configuration
config.ts contains the runtime configuration for your plugin. It must implement theMyPlugin interface we created above and define thehandler() function from theMyPlugin['Config'] interface.
import { definePluginConfig }from '@hey-api/openapi-ts';import { handler }from './plugin';import type { MyPlugin }from './types';export const defaultConfig: MyPlugin['Config']= { config: { myOption:false,// implements default value from types }, dependencies: ['@hey-api/typescript'], handler, name:'my-plugin',};/** * Type helper for `my-plugin` plugin, returns{@link Plugin.Config} object */export const defineConfig = definePluginConfig(defaultConfig);In the file above, we define amy-plugin plugin which will generate amy-plugin.gen.ts file. We also demonstrate declaring@hey-api/typescript as a dependency for our plugin, so we can safely import artifacts fromtypes.gen.ts.
By default, your plugin output won't be re-exported from theindex.ts file. To enable this feature, addincludeInEntry: true to yourconfig.ts file.
WARNING
Re-exporting your plugin from index file may result in broken output due to naming conflicts. Ensure your exported identifiers are unique.
Handler
Notice we definedhandler in ourconfig.ts file. This method is responsible for generating the actual output. We recommend implementing it inplugin.ts.
import type { MyPlugin }from './types';export const handler: MyPlugin['Handler']= ({plugin })=> { // create an output file. it will not be // generated until it contains nodes const file = plugin.createFile({ id: plugin.name, path: plugin.output, }); plugin.forEach('operation','schema', (event)=> { if (event.type=== 'operation') { // do something with the operation model }else if (event.type=== 'schema') { // do something with the schema model } }); // we're using the TypeScript Compiler API const stringLiteral = ts.factory.createStringLiteral('Hello, world!'); const variableDeclaration = ts.factory.createVariableDeclaration( 'foo', undefined, undefined, stringLiteral, ); const node = ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([variableDeclaration], ts.NodeFlags.Const), ); // add a node to our file file.add(node);};Legacy Handler
You can also define an optionalhandlerLegacy function inconfig.ts. This method is responsible for generating the output when using the legacy parser. We do not recommend implementing this method unless you must use the legacy parser. You can use one of ourplugin-legacy.ts files as an inspiration for potential implementation.
Usage
Once we're satisfied with our plugin, we can register it in theconfiguration file.
import { defineConfig }from 'path/to/my-plugin';export default { input:'hey-api/backend',// sign up at app.heyapi.dev output:'src/client', plugins: [ defineConfig({ myOption:true, }), ],};Output
Putting all of this together will generate the followingmy-plugin.gen.ts file.
export const foo = 'Hello, world!';Congratulations! You've successfully created your own plugin! 🎉
Examples
You can view live examples onStackBlitz.
Sponsors
Hey API is sponsor-funded. If you rely on Hey API in production, consider becoming asponsor 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
