mrkeyoor.com_
Sun 20 Sept 04:58 UTC
npmUtilsupdated 20 Sept 2026

zod-to-json-schema review

zod-to-json-schema 3.25.2 converts Zod v3 schemas into JSON Schema draft 7, draft 2019-09, OpenAPI 3.0, or an experimental OpenAI-oriented shape. It can emit references for repeated or recursive definitions, translate common string and numeric checks, alter additional-property handling, and let callbacks override or post-process generated nodes. The important current fact is retirement: the maintainer ended active maintenance in November 2025 because Zod 4 now generates JSON Schema itself, and GitHub marks the repository archived. Version 3.25.2 only raises its Zod 3 peer floor to 3.25.28 after earlier 3.25 patches caused out-of-memory problems or lacked the `/v3` compatibility import.

43.6Mdownloads / wk
Verdict

Do not add zod-to-json-schema to a new project: it is archived, maintenance has ended, and Zod 4 contains the intended replacement. Keep 3.25.2 only where v3 compatibility or exact historical output still matters, lock it, test emitted schemas, and schedule removal.

We installed it

Lab card: what happened when we installed zod-to-json-schemaScreenshot of zod-to-json-schema documentation
Install✓ · 0.7s7 packages on disk · 8 MB
ImportESM import works · require() works · CommonJS package with exports map
Browser18.7 KBgzipped (76.6 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does zod-to-json-schema install cleanly?

Yes. In a fresh container with an empty cache, npm install zod-to-json-schema finished in 0.7s, leaving 7 packages and 8 MB on disk. npm audit reported no known vulnerabilities.

How much does zod-to-json-schema add to a browser bundle?

18.7 KB gzipped (76.6 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does zod-to-json-schema work with both ESM and CommonJS?

Yes. Both import 'zod-to-json-schema' and require('zod-to-json-schema') worked in Node 22 in our run. The package is published as CommonJS with an exports map.

Does zod-to-json-schema include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

zod-to-json-schema or zod: which should you use?

zod: Use Zod 4's built-in z.toJSONSchema() for new work and migrations from this archived converter. Do not add zod-to-json-schema to a new project: it is archived, maintenance has ended, and Zod 4 contains the intended replacement.

When should you not use zod-to-json-schema?

This is a new Zod 4 project. Zod now provides z.toJSONSchema() in the maintained core package, which is the successor named in this repository's deprecation notice.

API stability2/5The package has one main conversion function and a documented options object, which makes pinned use straightforward. Its own versioning section says it does not follow semantic versioning: major and minor numbers follow Zod feature parity, and features have shipped as patches. Version 3.25.2 exists to repair the usable peer range after nearby Zod patches caused an out-of-memory failure or removed an import alias. An archived package will not adapt if Zod or consumers expose another incompatibility.
Docs4/5The README is detailed about naming, definitions, reference strategies, targets, dates, emails, base64, unions, additional properties, callbacks, error messages, metadata, recursion, Zod 4 peer caveats, and known conversion gaps. It states the deprecation and non-semantic versioning plainly. Documentation is one long repository page plus a changelog, with no versioned API site, and some advanced combinations are described as experimental or unsupported rather than demonstrated against current providers.
Maintenance1/5GitHub reports an archived repository, zero open issues and pull requests because new activity is disabled, 1,251 stars, and a last push on March 27, 2026. The README says active maintenance ended in November 2025 and directs users to Zod 4. Release 3.25.2 was a final compatibility correction around the Zod v3 floor, while the older GitHub release page was not kept current with npm. There is no credible route for a newly discovered parser bug to be merged here.
Ecosystem3/5npm counted 56,847,701 downloads in the latest completed week, and the converter remains embedded in API, OpenAPI, agent, and tool-schema stacks that still use Zod 3. It supports CommonJS, ESM, bundled declarations, several schema targets, recursive references, and callback customization. That reach is installed-base inertia rather than future direction: Zod 4 moved generation into core, and downstream packages can migrate without selecting a new third-party converter.

Use it if

  • A pinned dependency still owns Zod v3 schemas and replacing its converter is outside the current change scope.
  • An existing production path already depends on this package's exact reference layout, OpenAPI 3.0 mode, callback options, or OpenAI target and has regression fixtures for the output.
  • A Zod 4 project must temporarily convert schemas deliberately authored through `zod/v3` while a staged migration is underway.
  • You are auditing a transitive install and need to understand why an agent, MCP, or API tool emits a particular JSON Schema shape.
Skip it if

Setup reality

We installed zod-to-json-schema 3.25.2 in a fresh Node 22 Bookworm container. npm completed in 0.7 seconds, left 7 packages, and used 8 MB. The package has no direct dependencies, one peer dependency, and 656 KB unpacked under the ISC license. npm audit found zero known vulnerabilities. Both require() and ESM import worked, and TypeScript declarations are bundled. Our full import built to 76.6 KB minified and 18.7 KB gzipped.

Install Zod separately and respect the peer floor ^3.25.28 || ^4. That ^4 range does not mean v4 schema support. In a Zod 4 dependency tree, import z from zod/v3 for every schema passed to this converter. Version 3.25.2 raised the v3 minimum because earlier 3.25 releases either triggered an out-of-memory problem or removed the compatibility alias. Mixing constructors from native v4 and the v3 compatibility layer can survive installation and fail when conversion runs.

Default output is JSON Schema draft 7. Naming a schema wraps it in a definitions collection and returns a root reference. Objects usually emit additionalProperties: false; some downstream providers want the keyword absent or impose their own strict-object rules. Reference strategies change output size and recursion behavior. With $refStrategy: 'none', repeated structures are copied and recursive branches can degrade to an unconstrained schema. Snapshot the exact emitted document consumed by an API instead of checking only TypeScript compilation.

Conversion describes what Zod validates on input. A transform's output function is runtime code, so the generated schema can describe the wrong side for downstream consumers. The OpenAI target is marked experimental, relative JSON pointers have poor resolver support, and draft 2020-12 is not officially supported. Override callbacks use a special ignoreOverride sentinel; returning undefined removes the node. Because the project is archived, keep any remaining use behind fixtures and plan a Zod 4 migration rather than adding new option combinations.

Patterns

Generate draft 7 from a Zod v3 object convert-basic-schema

import { z } from 'zod/v3';
import { zodToJsonSchema } from 'zod-to-json-schema';

const User = z.object({
  name: z.string().min(2),
  age: z.number().int().optional(),
});

const jsonSchema = zodToJsonSchema(User);

Use the v3 entry when Zod 4 is installed. Default output targets draft 7 and normally disallows unknown object properties through `additionalProperties: false`.

Place a named schema behind a reference name-definition

const jsonSchema = zodToJsonSchema(User, {
  name: 'User',
  definitionPath: '$defs',
});

Naming changes the root shape to a `$ref` plus a definitions collection. Confirm the receiving library resolves references before enabling it.

Emit the OpenAPI 3.0 dialect target-openapi-3

const schema = zodToJsonSchema(User, {
  target: 'openApi3',
  $refStrategy: 'none',
});

OpenAPI 3.0 differs from newer JSON Schema behavior, including nullable representation. OpenAPI 3.1 consumers should normally use regular JSON Schema instead.

Generate the package's OpenAI shape target-openai

const Args = z.object({
  city: z.string(),
  units: z.enum(['c', 'f']).optional(),
});

const parameters = zodToJsonSchema(Args, {
  target: 'openAi',
  $refStrategy: 'none',
});

The README labels this target experimental. Validate the emitted schema against the exact API and model endpoint before caching or publishing it.

Reference one sub-schema in several places share-definitions

const Address = z.object({
  street: z.string(),
  postalCode: z.string(),
});
const Order = z.object({ billing: Address, shipping: Address });

const schema = zodToJsonSchema(Order, {
  definitions: { Address },
});

Explicit definitions can prevent repeated copies. The reference path also depends on `definitionPath`, schema naming, and base-path options.

Inline output for a consumer without `$ref` inline-references

const schema = zodToJsonSchema(Order, {
  $refStrategy: 'none',
});

Inlining expands repeated branches and cannot expand recursion forever. Inspect recursive schemas because the converter may replace the recursive point with an unconstrained object.

Remove additional-property keywords omit-additional-properties

const schema = zodToJsonSchema(User, {
  allowedAdditionalProperties: undefined,
  rejectedAdditionalProperties: undefined,
});

These options do not override an explicit `.catchall()` schema. Omitting the keyword changes how downstream validators apply their own defaults.

Carry supported Zod messages into AJV metadata emit-error-messages

const Email = z
  .string()
  .email('Invalid email')
  .min(5, 'Too short');

const schema = zodToJsonSchema(Email, {
  errorMessages: true,
});

The emitted `errorMessage` keyword is an AJV extension, not standard JSON Schema. It has an effect only when the consumer installs and enables compatible support.

Expand metadata from a JSON description add-json-metadata

import { jsonDescription, zodToJsonSchema } from 'zod-to-json-schema';

const City = z.string().describe(JSON.stringify({
  title: 'City',
  description: 'Delivery city',
  examples: ['Ahmedabad', 'Pune'],
}));

const schema = zodToJsonSchema(City, { postProcess: jsonDescription });

This is a Zod v3 workaround that treats description text as JSON. Zod 4 has its own metadata and JSON Schema generation path.

Replace one generated property override-node

import { ignoreOverride, zodToJsonSchema } from 'zod-to-json-schema';

const schema = zodToJsonSchema(User, {
  override(definition, refs) {
    if (refs.currentPath.join('/') === '#/properties/age') {
      return { type: 'integer', minimum: 0 };
    }
    return ignoreOverride;
  },
});

Return `ignoreOverride` when no replacement is intended. Returning `undefined` deliberately filters the node out of the generated document.

Keep legacy schemas isolated in a Zod 4 tree convert-v3-under-zod-4

import { z as z3 } from 'zod/v3';
import { zodToJsonSchema } from 'zod-to-json-schema';

const LegacyInput = z3.object({
  id: z3.string().uuid(),
});

const schema = zodToJsonSchema(LegacyInput);

Version 3.25.2 requires a Zod release where the `/v3` alias exists. Do not pass a schema constructed by the native Zod 4 API.

Use Zod 4 without this converter migrate-to-zod-4

import { z } from 'zod';

const User = z.object({
  name: z.string().min(2),
  age: z.number().int().optional(),
});

const schema = z.toJSONSchema(User, {
  target: 'draft-7',
});

Zod 4 output is not guaranteed to match this package byte for byte. Diff representative recursive, transformed, optional, and metadata-heavy schemas against every downstream consumer.

Alternatives

PackageRegistryPick it when
zodnpmUse Zod 4's built-in `z.toJSONSchema()` for new work and migrations from this archived converter.
zod-openapinpmUse it when the maintained output is an OpenAPI document with Zod-backed components and operations rather than standalone JSON Schema.
@asteasolutions/zod-to-openapinpmUse it when an existing Zod codebase needs explicit OpenAPI metadata, registries, and document generation.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · 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.