Generate TypeScript-first JSON Schemas (.ts
modules with as const
) directly from your OpenAPI definitions — so you can use the same schema for both runtime validation and TypeScript type inference.
Keeping OpenAPI specs, runtime validators, and TypeScript types in sync is hard.
Many teams end up maintaining the same api models in different formats:
- JSON Schema for runtime validation (
Ajv
,Fastify
, etc.) - TypeScript types for static checking
openapi-ts-json-schema
solves this by generating TypeScript JSON Schemas directly from your OpenAPI definitions: valid JSON schemas written as TypeScript modules, ready for runtime validation and type inference.
These schemas:
- ✅ are 100% JSON Schema–compatible (usable with
Ajv
,Fastify
, etc.) - ✅ are TypeScript-native (
as const
objects you can import) - ✅ can be used for type inference via json-schema-to-ts
- ✅ are generated automatically from your OpenAPI spec
In short: OpenAPI spec becomes the single source of truth for both runtime validation and TypeScript typing.
From this OpenAPI definition:
components:
schemas:
User:
type: object
properties:
id: { type: string }
name: { type: string }
required: [id, name]
You get this TypeScript JSON schema:
// components/schemas/User.ts
export default {
type: 'object',
properties: {
id: { type: 'string' },
name: { type: 'string' },
},
required: ['id', 'name'],
} as const;
Now you can use it for both runtime validation and type inference:
import Ajv from 'ajv';
import type { FromSchema } from 'json-schema-to-ts';
import userSchema from './components/schemas/User';
const ajv = new Ajv();
const validate = ajv.compile<FromSchema<typeof userSchema>>(userSchema);
const data: unknown = {};
if (validate(data)) {
// data is now typed as { id: string; name: string }
} else {
console.error(validate.errors);
}
Given an OpenAPI definition file, openapi-ts-json-schema
:
- Resolves and dereferences $refs (using @apidevtools/json-schema-ref-parser)
- Converts OpenAPI objects to JSON Schema (via @openapi-contrib/openapi-schema-to-json-schema &
openapi-jsonschema-parameters
) - Generates
.ts
files exporting each schema asas const
- Mirrors the original OpenAPI structure in the generated folder
- Supports plugins (e.g. for Fastify integration)
Take a look at the Developer's notes for a few more in-depth explanations.
npm i openapi-ts-json-schema -D
Generate your TypeScript JSON schemas:
import { openapiToTsJsonSchema } from 'openapi-ts-json-schema';
const { outputPath } = await openapiToTsJsonSchema({
openApiDocument: 'path/to/open-api-specs.yaml',
definitionPathsToGenerateFrom: ['paths', 'components.schemas'],
});
Schemas are generated in a folder mirroring your OpenAPI layout (default: schemas-autogenerated
).
Property | Type | Description | Default |
---|---|---|---|
openApiDocument (required) | string |
Path to the OpenApi file (supports yaml and json). | - |
definitionPathsToGenerateFrom (required) | string[] |
OpenAPI object paths to generate schemas from. Eg: ["components.schemas"] . |
- |
refHandling | "import" | "inline" | "keep" |
"import" : generate and import $ref schemas."inline" : inline $ref schemas."keep" : keep $ref values. |
"import" |
idMapper | (params: { id: string }) => string |
Customize generated schemas $id s and $ref s values |
- |
schemaPatcher | (params: { schema: JSONSchema }) => void |
Dynamically patch generated JSON schemas. The provided function will be invoked against every single JSON schema node. | - |
outputPath | string |
Path where the generated schemas will be saved. Defaults to /schemas-autogenerated in the same directory of openApiDocument . |
- |
plugins | ReturnType<Plugin>[] |
A set of optional plugins to generate extra custom output. See plugins docs. | - |
silent | boolean |
Don't log user messages. | false |
Three strategies for how $ref
s are resolved:
refHandling option |
description |
---|---|
inline |
Inlines $refs s, creating self-contained schemas (no imports, but possible redundancy). |
import |
Replaces$ref s with imports of the target definition |
keep |
Leaves $ref s untouched — useful if you plan to interpret $ref s dynamically or use a plugin |
Circular references are supported:
inline
: circular refs are replaced with{}
import
: resolves the JSON schema but TypeScript recursion halts (any
type, TS error 7022)keep
: circular refs left unresolved
See tests for details.
Along with generated schema files, openapi-ts-json-schema
returns metadata:
{
// The path where the schemas are generated
outputPath: string;
metaData: {
// Meta data of the generated schemas
schemas: Map<
// Schema internal id. Eg: "/components/schemas/MySchema"
string,
{
id: string;
// Internal unique schema identifier. Eg `"/components/schemas/MySchema"`
$id: string;
// JSON schema Compound Schema Document `$id`. Eg: `"/components/schemas/MySchema"`
uniqueName: string;
// Unique JavaScript identifier used as import name. Eg: `"componentsSchemasMySchema"`
openApiDefinition: OpenApiObject;
// Original dereferenced openAPI definition
originalSchema: JSONSchema | string;
// Original dereferenced JSON schema
isRef: boolean;
// True if schemas is used as a `$ref`
shouldBeGenerated: boolean;
// Text content of schema file
fileContent?: string;
absoluteDirName: string;
// Absolute path pointing to schema folder (posix or win32). Eg: `"Users/username/output/path/components/schemas"`
absolutePath: string;
// Absolute path pointing to schema file (posix or win32). Eg: `"Users/username/output/path/components/schemas/MySchema.ts"`
absoluteImportPath: string;
// Absolute import path (posix or win32, without extension). Eg: `"Users/username/output/path/components/schemas/MySchema"`
}
>;
}
}
Extend openapi-ts-json-schema
with custom generators. Currently available plugins:
generateSchemaWith$idPlugin
fastifyIntegrationPlugin
- Consider removing required
definitionPathsToGenerateFrom
option in favour of exporting the whole OpenAPI definitions based on the structure defined in specs - Improve external
#ref
s handling (currently being inlined and duplicated) - Find a way to merge multiple different OpenApi definitions consistently
- Consider implementing an option to inline circular $refs with a configurable nesting level