New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@ata-project/zod

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ata-project/zod

Run zod schemas on the ata engine: same answers as zod, verdicts decided by compiled JSON Schema validation, refinements handed back to zod.

latest
Source
npmnpm
Version
0.3.1
Version published
Maintainers
1
Created
Source

@ata-project/zod

Run zod schemas on the ata engine. The schema stays zod. The verdict comes from compiled JSON Schema validation where that is provably safe, and from zod itself everywhere it is not.

npm i @ata-project/zod

zod 4 and ata-validator are peer dependencies; npm and pnpm install them automatically, yarn users add them alongside.

One zod schema, three ways to run it: measured times for accepting and rejecting documents, in Node and with code generation blocked

import { z } from 'zod'
import { compile } from '@ata-project/zod'

const user = z.object({
  id: z.number().int().min(1),
  name: z.string().min(1).max(64),
  email: z.string().email(),
})

const check = compile(user)

check.isValid(data)      // boolean, ata answers
check.safeParse(data)    // zod-shaped result, the value zod would return
check.parse(data)        // throws a real ZodError

Types carry through: safeParse returns z.output of your schema.

How it stays correct

zod 4 turns a schema into JSON Schema with z.toJSONSchema, and ata executes JSON Schema. That conversion is lossy in both directions: refinements and transforms are dropped silently, which makes the emitted schema looser than zod, and coercion is dropped too, which makes it stricter. A wrong answer in either direction is unacceptable, so compile classifies the schema by walking zod's own definition tree before anything runs:

ModeWhenWho answers
atathe conversion is exactata alone
hybridrefine, transform, pipe, Date and other non-JSON typesata's rejection is final; an acceptance runs zod for the residue
zodcoerce, catch, preprocess, or a node this package does not recognisezod, undecorated

The classification is conservative: an unrecognised node lands in zod mode, so a new zod feature can make this package slower, never wrong. The test suite holds isValid, safeParse and the parsed value against zod itself over 15,000 generated values across all three modes, including recursive schemas, and runs the whole suite a second time with code generation blocked.

compiled.engine tells you which mode you got, compiled.reasons says why.

What it costs, measured

One representative API-boundary object schema (nine fields, nested arrays of objects, enum, union), interleaved medians of 7 rounds on an M-series Mac, Node 25, zod 4.6.5, ata-validator 1.36.0, median of three runs:

zod safeParsez.compilethis package
accept, verdict only527 ns44 ns23 ns
reject, verdict only822 ns851 ns6 ns
reject, safeParse822 ns851 ns8.3 ns
accept, safeParse527 ns44 ns54.3 ns

An accepted value is built by ata's parse() wherever the classifier proves it comes out exactly as zod would build it: plain objects whose optional keys follow the required ones, arrays, primitives and unions of primitives, with nothing that fills a default, rewrites a value or keeps undeclared keys. The differential suite holds that value to zod's, key order included. Anything else, a default, a transform, a record, a union of objects, a loose object, hands the accepted value to zod, which returns exactly what it always did. This needs ata-validator 1.33.0 or later, which copies arrays instead of sharing them with the input; with an older ata every accepted value goes to zod. isValid never runs zod in ata mode, and a rejected safeParse builds its ZodError only when somebody reads it, by running zod once at that moment.

With code generation blocked, the way a strict CSP or a locked-down edge runtime blocks it (node --disallow-code-generation-from-strings):

zod safeParsez.compilethis package
accept, verdict only1290 ns1273 ns651 ns
reject, verdict only1695 ns1700 ns113 ns

z.compile does not fail there, but its advantage does: it runs at the speed of uncompiled zod. ata falls back to its interpreted engine, which passes the same official JSON Schema test suite as its compiled one.

Raw bytes

isValidBytes answers from a Buffer, Uint8Array or JSON string without JSON.parse and without materializing a JavaScript object, something zod has no path for at all:

const check = compile(schema)
check.isValidBytes(request.rawBody)   // boolean, straight from the bytes

On an engine: 'ata' schema with the native engine present, the verdict comes from a SIMD walk of the buffer. The same array-of-objects schema as above, interleaved medians of 7 rounds, first element invalid on the reject rows, measured on zod 4.5.4 and ata-validator 1.13.1:

payloadzod parse + safeParseisValidBytes
0.2 KB, accept0.9 us0.6 us
0.2 KB, reject1.6 us0.6 us
22.7 KB, accept79.2 us47.6 us
22.7 KB, reject81.0 us45.6 us
229 KB, accept793 us489 us
229 KB, reject791 us482 us

Bytes that are not valid JSON return false rather than throwing. The verdict agrees with safeParse on the parsed value; the differential suite compares the two on every JSON-representable value it generates.

Plainly: this is a verdict, not a parse. When you need the value, you still parse and safeParse it, and hybrid and zod mode schemas, and installs without the native engine, do exactly that under the hood. The API is worth having where rejection is the common case: gateways, webhook endpoints and queue consumers that drop bad messages before doing any further work.

Limitations, plainly

  • Accepted values in hybrid mode, accepted values whose shape ata cannot build exactly as zod does, and every value in zod mode run zod, so those paths are zod-speed.
  • Value-rewriting checks such as .trim() and .toLowerCase() put a schema in zod mode. They do not reach the JSON Schema, and they can make zod accept what the schema rejects as well as the other way round. 0.2.1 and earlier missed them and could answer isValid wrongly; upgrade if you use them.
  • validate() reports ata's errors for the schema-representable part, which are JSON Schema errors, not ZodError issues. Use safeParse when you need zod's error shape.
  • The classifier reads schema._zod.def, which is zod's internal tree. The peer range is pinned to zod 4 and the differential suite is the tripwire for internals moving.
  • Async refinements are not supported; safeParse is synchronous, as in zod.

Standard Schema

The compiled object implements Standard Schema V1, so anything that accepts a standard schema runs the fast path without knowing either library:

const result = check['~standard'].validate(data)

License

MIT

Keywords

zod

FAQs

Package last updated on 28 Sep 2026

Related posts