mrkeyoor.com_
Sat 08 Aug 22:54 UTC
npmCLI & Toolingupdated 08 Aug 2026

json-schema-to-typescript

json-schema-to-typescript turns JSON Schema files or JavaScript schema objects into TypeScript declaration text. Its json2ts CLI accepts JSON, YAML, stdin, files, directories, and globs; its API exposes compile and compileFromFile for build scripts. It resolves local and remote $ref links, emits interfaces, unions, enums, tuples, comments, and index signatures, then formats the result with Prettier by default. The output describes values to TypeScript but does not validate a single value at runtime.

Verdict

A practical generator when JSON Schema owns the contract and erased validation rules are understood. Do not mistake readable .d.ts output for runtime safety or full JSON Schema equivalence.

API stability3/5The compile, compileFromFile, and json2ts entry points are established, and the current options are explicitly documented with defaults. Generated text is still a sensitive API: the changelog describes major releases where bug fixes intentionally changed emitted unions, intersections, enums, names, and schema parsing. Even a correct fix can create a large declaration diff or expose downstream TypeScript errors, so pin the version and review generated changes.
Docs4/5The README supplies CLI forms for stdin, files, YAML, directories, and globs; a full options table; programmatic examples; a feature matrix; custom extensions; and a candid list of rules TypeScript cannot express. The architecture document and snapshots add depth for contributors. A few rough edges remain: documentation is concentrated in one long page, the partial changelog omits many fixes, and CLI help behavior around implicit output is less clear than explicit redirection.
Maintenance4/5The repository is not archived and was pushed on August 6, 2026. A concentrated August commit set fixed dropped nested properties, reference naming, index signatures, bounded-array expansion, enum naming, null handling, and added fuzz testing. The latest npm release is still 15.0.4 from January 2025, so current repository fixes are not evidence that installed users have received them yet; GitHub also reports 203 open issues and pull requests combined.
Ecosystem4/5The package recorded 3,183,895 downloads in the measured week and the README names consumers including Amazon, Expo, Microsoft, Mozilla, Nx, Sourcegraph, Stryker, and Webpack. JSON Schema input, YAML support, Prettier output, and $ref resolution fit common build systems. It remains narrower than OpenAPI code generators and does not share a runtime validator's guarantee, so many production setups still need Ajv alongside it.

Use it if

  • JSON Schema is already the source of truth and TypeScript consumers need generated declarations kept in sync
  • You need a CLI that can convert a directory or quoted glob of JSON and YAML schemas into matching .d.ts files
  • Your schemas use definitions, $defs, local or external $ref links, enums, unions, intersections, or bounded arrays that hand-written interfaces would duplicate
  • You want a programmable compiler with naming, formatting, reference-resolution, and output strictness options
Skip it if

Setup reality

Install the package locally and run its json2ts binary with npx json2ts; npx json-schema-to-typescript is not the documented command. Version 15.0.4 requires Node 16 or newer and brings nine runtime dependencies, including Prettier 3, js-yaml, lodash, tinyglobby, and json-schema-ref-parser. There is no required config file. CLI options are flags, including nested flags such as --style.singleQuote, while programmatic callers pass an options object. Input may be JSON or YAML. With stdin or a single file, use stdout redirection or an explicit output path so generated declarations land where expected. Quote globs so the tool expands them consistently, and send directory or glob input to an output directory; the CLI source explicitly rejects a multi-file input paired with one .d.ts output. Reference paths depend on cwd: compileFromFile automatically bases them on the input file's directory, while compile on an object defaults to process.cwd() unless overridden. External references are declared by default and may involve network access. Schemas without additionalProperties explicitly set are treated as open because the package default is true, often producing an index signature broader than teams expect. Set additionalProperties: false in the schema when closed objects are intended. Definitions not reachable from the root are omitted unless unreachableDefinitions is enabled. Bounded arrays can expand into unions of tuple lengths up to the maxItems threshold of 20; ignoreMinAndMaxItems or maxItems controls that precision and cost. Formatting is on by default and uses bundled Prettier settings. The README warns that Prettier can be slow enough to crash on giant output, so use format: false for large generation jobs and format once afterward. Generated TypeScript is an artifact, not a replacement for schema tests: diff it in CI and keep a real JSON Schema validator on data boundaries.

Patterns

Generate a declaration from one schemagenerate-interface

npx json2ts --input schemas/user.json --output generated/user.d.ts

The executable is json2ts. Keep the JSON Schema as the edited source and regenerate the .d.ts file instead of changing generated output by hand.

Compile a schema through stdin and stdoutpipe-stdin

cat schemas/user.json | npx json2ts > generated/user.d.ts

Shell redirection makes the destination unambiguous. Errors go to stderr and the CLI exits nonzero when parsing or generation fails.

Compile a YAML schemacompile-yaml-schema

npx json2ts schemas/order.yaml generated/order.d.ts

YAML support uses js-yaml. The resulting type has the same semantic limits as JSON input, including erased validation-only constraints.

Generate matching files from a directorycompile-schema-directory

npx json2ts --input schemas --output generated/types

Directory input is recursive and expects an output directory. Do not pair multi-file input with a single .d.ts destination.

Generate declarations from a globcompile-schema-glob

npx json2ts --input 'schemas/**/*.schema.json' --output generated/types

Quote the glob so json2ts, rather than the shell, discovers the files. An unmatched pattern is treated as an error.

Compile a schema object in a build scriptcompile-schema-object

import {compile} from 'json-schema-to-typescript';
import {writeFile} from 'node:fs/promises';

const schema = {
  type: 'object',
  additionalProperties: false,
  properties: {id: {type: 'string'}, active: {type: 'boolean'}},
  required: ['id'],
};

const source = await compile(schema, 'Account');
await writeFile('generated/account.d.ts', source);

compile needs an explicit root type name. additionalProperties: false prevents the generated interface from accepting arbitrary extra keys.

Compile a file with local referencescompile-schema-file

import {compileFromFile} from 'json-schema-to-typescript';
import {writeFile} from 'node:fs/promises';

const source = await compileFromFile('schemas/invoice.json');
await writeFile('generated/invoice.d.ts', source);

compileFromFile bases reference resolution on the schema file's directory, which is safer than relying on the process working directory.

Set the $ref resolution rootset-reference-root

const source = await compile(schema, 'Invoice', {
  cwd: new URL('./schemas/', import.meta.url).pathname,
  declareExternallyReferenced: true,
});

Remote and file references are dereferenced by json-schema-ref-parser. Restrict its $refOptions resolvers when schemas are not fully trusted.

Emit definitions that the root does not referenceemit-unused-definitions

npx json2ts -i schemas/catalog.json -o generated/catalog.d.ts --unreachableDefinitions

unreachableDefinitions defaults to false. Enable it only when consumers import standalone definitions that are not reachable from the root schema.

Generate stricter index signaturestighten-index-signatures

const source = await compile(schema, 'Dictionary', {
  strictIndexSignatures: true,
  additionalProperties: false,
});

The option appends undefined to index-signature values for stricter access. It does not close schemas that explicitly permit additional properties.

Avoid tuple explosions from array boundscontrol-bounded-arrays

const source = await compile(schema, 'Report', {
  ignoreMinAndMaxItems: true,
  maxItems: 20,
});

With bounds enabled, arrays may become unions of tuple lengths. Ignore bounds when a simpler T[] is preferable to exact compile-time length.

Skip built-in formatting for a large schemaspeed-up-large-generation

const source = await compile(largeSchema, 'Catalog', {
  format: false,
  bannerComment: '/* generated file */',
});

The README identifies Prettier as a failure and performance point on giant output. Format once in a later build step if readable generated code is still required.

Alternatives

PackageRegistryPick it when
quicktypenpmYou need types or models in several languages and may start from sample JSON as well as JSON Schema
json-schema-to-tsnpmSchemas live as TypeScript const values and you want inferred types without generating .d.ts files
@sinclair/typeboxnpmA TypeScript-first codebase wants schemas and static types created together from one builder API
@hey-api/openapi-tsnpmThe source is an OpenAPI document and you need clients, SDKs, and service types rather than generic schema declarations