json-schema-to-typescript review
json-schema-to-typescript 15.0.4 compiles JSON Schema into TypeScript declaration text. Its `json2ts` CLI accepts JSON, YAML, stdin, individual files, directories, and globs; code can call `compile` or `compileFromFile`. It resolves `$ref`, emits interfaces, unions, enums, tuples, comments, and index signatures, then runs Prettier unless formatting is disabled. The generated types vanish at runtime, and several schema constraints cannot be represented in TypeScript. Our install found bundled declarations and successful CommonJS and ESM loading, while browser bundling failed because this package is Node-oriented tooling.
json-schema-to-typescript 15.0.4 installed in 1.8 seconds with 15 packages and 22 MB in our sandbox, passed npm audit, and failed browser bundling as expected for Node build tooling. Install it when JSON Schema is already authoritative, but keep runtime validation because the generated `.d.ts` cannot enforce the full schema.
We installed it
| Install | ✓ · 1.8s | 15 packages on disk · 22 MB |
| Import | ✓ | ESM import works · require() works · CommonJS package |
| Browser | n/a | could not be bundled for the browser (Node-only code, most likely) |
| Types | ✓ | TypeScript types bundled |
| Known vulns | 0 | 0 critical · 0 high · 0 moderate · 0 low (npm audit) |
Answers from our run
Does json-schema-to-typescript install cleanly?
Yes. In a fresh container with an empty cache, npm install json-schema-to-typescript finished in 2 seconds, leaving 15 packages and 22 MB on disk. npm audit reported no known vulnerabilities.
Can json-schema-to-typescript run in a browser?
Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.
Does json-schema-to-typescript work with both ESM and CommonJS?
Yes. Both import 'json-schema-to-typescript' and require('json-schema-to-typescript') worked in Node 22 in our run. The package is published as CommonJS.
Does json-schema-to-typescript include TypeScript types?
Yes, type declarations ship inside the package, so no @types install is needed.
json-schema-to-typescript or json-schema-to-ts: which should you use?
json-schema-to-ts: Use it when schemas are TypeScript as const values and inferred types should require no generated files. json-schema-to-typescript 15.0.4 installed in 1.8 seconds with 15 packages and 22 MB in our sandbox, passed npm audit, and failed browser bundling as expected for Node build tooling.
When should you not use json-schema-to-typescript?
You need runtime validation. Interfaces do not enforce format, pattern, numeric bounds, uniqueness, or any other rule after TypeScript compilation.
Use it if
- JSON Schema owns the contract and TypeScript declarations should be generated from it in CI.
- A directory or quoted glob of JSON and YAML schemas must become matching `.d.ts` files.
- Schemas use local or external `$ref`, definitions, enums, unions, intersections, or bounded arrays that would be tedious to mirror by hand.
- A build script needs control over names, index signatures, unreachable definitions, formatting, and reference resolution.
- You need runtime validation. Interfaces do not enforce `format`, `pattern`, numeric bounds, uniqueness, or any other rule after TypeScript compilation.
- `oneOf` must mean exclusive choice. The README says version 15.0.4 treats it like `anyOf`, so values matching multiple branches remain assignable.
- The schema depends on constraints TypeScript cannot express, including `minimum`, `maximum`, `multipleOf`, property counts, `not`, or `uniqueItems`.
- Untrusted schemas can contain external `$ref` links. The resolver can access files or networks unless its parser options are restricted and the job is isolated.
- This compiler must run in shipped browser code. Our browser bundle failed, and the 22 MB installed toolchain belongs in generation or CI rather than a frontend.
Setup reality
We installed json-schema-to-typescript 15.0.4 in 1.8 seconds in our fresh Node 22 sandbox. It left 15 packages and 22 MB on disk, and npm audit reported 0 known vulnerabilities. The package has 9 direct dependencies, 0 peers, 384 KB unpacked, an MIT license, and a Node floor of 16. It is CommonJS without an exports map; require() and ESM import worked, and TypeScript declarations are bundled.
The executable is json2ts, not the package name. No config file is required: CLI callers pass flags, while API callers pass an options object. Quote globs so the tool expands them consistently. A directory or multi-file glob needs an output directory, not one .d.ts path. compileFromFile uses the schema file's directory for $ref; compile defaults to process.cwd() unless cwd is supplied.
Open objects are the default because additionalProperties defaults to true when the schema omits it. Set additionalProperties: false where extra keys should be rejected by the generated interface. Unreferenced definitions are skipped unless unreachableDefinitions is enabled. Array minItems and maxItems may expand into unions of tuple lengths up to the default threshold of 20; ignoreMinAndMaxItems trades that precision for smaller declarations.
Our esbuild browser attempt failed, which matches a Node CLI that reads files, resolves references, parses YAML, and formats output. Prettier runs by default; the README warns it can become slow or crash on giant generated files, so set format: false and format once later when needed. Pin version 15.0.4 and review generated diffs because compiler fixes can legitimately change unions, names, and index signatures. Keep Ajv or another validator on runtime data boundaries.
Patterns
Compile one JSON schema generate-interface
npx json2ts --input schemas/user.json --output generated/user.d.tsThe version 15.0.4 binary is `json2ts`; edit the schema and regenerate instead of patching the `.d.ts` artifact.
Send a schema through stdin pipe-stdin
cat schemas/user.json | npx json2ts > generated/user.d.tsShell redirection makes the single destination explicit, while parse and generation failures still leave through stderr with a nonzero exit.
Compile YAML input compile-yaml-schema
npx json2ts schemas/order.yaml generated/order.d.tsYAML is parsed by `js-yaml`; the output still omits runtime-only constraints such as `pattern` and numeric bounds.
Generate a directory tree compile-schema-directory
npx json2ts --input schemas --output generated/typesDirectory input is recursive and requires an output directory. One `.d.ts` destination cannot receive multiple input files.
Expand a quoted schema glob compile-schema-glob
npx json2ts --input 'schemas/**/*.schema.json' --output generated/typesQuote the pattern so `json2ts` controls discovery; an unmatched glob is reported as an error rather than an empty success.
Generate from an in-memory schema compile-schema-object
import { compile } from 'json-schema-to-typescript';
const schema = {
type: 'object',
additionalProperties: false,
properties: { id: { type: 'string' } },
required: ['id'],
};
const source = await compile(schema, 'Account');`compile` needs a root type name. Setting `additionalProperties: false` prevents the default open index signature.
Resolve references beside a file compile-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` anchors relative `$ref` paths at the schema file's directory instead of an arbitrary process working directory.
Choose the reference base set-reference-root
const source = await compile(schema, 'Invoice', {
cwd: new URL('./schemas/', import.meta.url).pathname,
declareExternallyReferenced: true,
});Version 15.0.4 can resolve file and network references; restrict `$refOptions` resolvers before processing third-party schemas.
Include unreferenced definitions emit-unused-definitions
npx json2ts -i schemas/catalog.json -o generated/catalog.d.ts --unreachableDefinitionsThe default is `false`; enable this only when consumers import definitions that the root schema never reaches.
Add undefined to indexed reads tighten-index-signatures
const source = await compile(schema, 'Dictionary', {
strictIndexSignatures: true,
additionalProperties: false,
});`strictIndexSignatures` changes indexed value types; it does not close a schema that explicitly allows additional properties.
Avoid tuple-union growth control-bounded-arrays
const source = await compile(schema, 'Report', {
ignoreMinAndMaxItems: true,
maxItems: 20,
});The default `maxItems` threshold is 20; ignoring bounds produces a simpler array type when exact tuple lengths cost too much.
Disable the formatter for large output speed-up-large-generation
const source = await compile(largeSchema, 'Catalog', {
format: false,
bannerComment: '/* generated file */',
});The README identifies Prettier as a slow or crashing step on giant files; format the finished output once in a later job if required.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| json-schema-to-ts | npm | Use it when schemas are TypeScript `as const` values and inferred types should require no generated files. |
| quicktype-core | npm | Use it when the same schema or sample JSON must generate models in several programming languages. |
| @sinclair/typebox | npm | Use it when a TypeScript builder should create runtime JSON Schemas and static types together. |
More cli & tooling guides
chalk · commander · typescript · esbuild · yargs · click · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.

