Bump zod to 4.6.2 - #23588
Open
code-infra-renovate[bot] wants to merge 1 commit into
Open
Bump zod to 4.6.2#23588code-infra-renovate[bot] wants to merge 1 commit into
code-infra-renovate[bot] wants to merge 1 commit into
Conversation
Deploy previewBundle size
Check out the code infra dashboard for more information about this PR. |
code-infra-renovate
Bot
force-pushed
the
renovate/code-infra-devdependencies
branch
from
September 14, 2026 11:26
7441d27 to
00288a4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
4.5.4→4.6.2Release Notes
colinhacks/zod (zod)
v4.6.2Compare Source
A patch on top of 4.6.1.
9446b5ccfix: preserve undefined prefault outputs and object keys (#6587) — closes #65850c483c58docs: the Zod 4.6 announcement post (#6546)a00c3f34docs: use Trigger.dev's brand-kit lockups for the platinum cardv4.6.1Compare Source
A patch on top of 4.6.0.
b12aa523fix: preserve unique tags with defaulted discriminators (#6582) — closes #6577dd9c36fafix(v4): defer recursive object index inference (#6580)3b154992feat(lang): add Tajik (tg) locale (#6581) by @ismoil772efa8b80ci: give the npm wait a real budget and drop the back-publish path (#6583)v4.6.0Compare Source
Zod 4.6 is now available.
At a glance:
.validate()— checks input validity without building a result (up to 35x faster than.safeParse().successon a compiled schema)z.instanceof().properties()— validates properties of an instancefromJSONSchema()— enforces six validation keywords it used to ignorez.iban()— electronic-format IBAN plus mod-97 checksumz.withParser()— installs a parser generated elsewhere, for environments withoutnew Functionz.validate()underrequire)@zod/mini— Zod Mini as a standalone package, versioned in lockstep withzodsince 4.5.validate()Standalone boolean validation, in Zod, Zod Mini, and Zod Core. It answers "is this input valid?" without constructing a
ZodError, which makes rejection cheap. The return type is a guard on the schema's input type.It is a method on Zod Classic schemas too. (#6547)
In conjunction with
z.compile(), this can be up to 35x faster than.safeParse().successon invalid input.Time per call on invalid input, compiled with z.compile() — lower is better (benchmark)
Uncompiled schemas
Without compilation it is up to 5.9x faster. The saving is the result object:
.safeParse()allocates one with an accessor pair on every call, and.validate()allocates nothing.Time per call on invalid input, plain schemas — lower is better (benchmark)
Both charts measure the failure path. The key feature of
.validate()is that it can short-circuit on the first issue it encounters, instead of aggregating a fullZodIssue[]array.z.properties()A new API for validating specific properties of an object. Unlike
z.object()it validates in-place, so it plays nice with class instances. (#6536)A corresponding
.properties()method has been added toZodInstanceOf.Zod
Zod Mini
The input comes back untouched, so the prototype survives and the methods still work. That is the part
z.object()cannot do: it would hand back a plain object and theResponsewould be gone.fromJSONSchema()Six additional JSON Schema keywords are now supported in
z.fromJSONSchema(). (#6535)minProperties/maxPropertiesuniqueItemscontainsminContains/maxContainsBoth property bounds count the input's own keys. Array uniqueness is structural, so
[{ a: 1 }, { a: 1 }]is a duplicate.z.iban()A new string format: an IBAN in electronic format, with a valid ISO 7064 MOD 97-10 checksum. (#6571)
z.withParser()z.compile()builds its parser withnew Function, which a strict Content Security Policy blocks.z.withParser()is that installer on its own: it takes a parser generated somewhere else, at build time or by a native compiler, and installs it under the same contract. (#6575)The supplied parser owns the whole result, so it has to return what the schema would have returned. This one rebuilds the object rather than handing back its input, because
z.object()strips unknown keys. Returningz.INVALIDhands the input to the runtime, which stays the only source ofZodErrors.Faster CommonJS
TypeScript compiles a re-export to a getter, and 252 of the 255 exports on Zod 4.5's CommonJS entrypoint were getters. V8 could not see a constant callee behind one, so it could not inline the call. The 4.6 build emits plain properties and freezes the exports object. On a compiled schema,
z.validate()underrequireis about 3x faster than it was in Zod 4.5. (#6564)Only calls through the namespace were affected. A method call like
Player.safeParse(data)never reads the exports object, and the ESM build is unchanged.Memory retention in recursive schemas
A recursive schema held the input and output of its last parse until the next parse replaced it, so one long-lived schema pinned every object it had touched. Zod 4.4 released that input and Zod 4.5 did not, which surfaced as an out-of-memory failure on a repository-wide lint run. The parse state is weak throughout now: one parse of a 29k-node tree retains 2.2 MB where it used to retain 10.1 MB, and recursive parses give up about 6% for it. (#6572)
Bug fixes
errorBecause
safeParse()now builds its error lazily, error maps — global, locale, and per-schemaerror— run whenresult.erroris first read, not at parse time. Code that swapsz.config()between the parse and the read gets the newer configuration. (#6519)An error map with a side effect never runs if nothing reads the error. Throwing parses are unaffected —
.parse()builds and throws its error immediately, never takes the lazy path, and its stack still points at your call site.z.emoji()rejects component-only stringsUnicode's
Emoji_Componentproperty covers the pieces that attach to an emoji, soz.emoji()accepted"123","#","*", and a lone zero-width joiner, variation selector, or skin tone modifier. The pattern now requires at least one pictograph, regional indicator, or keycap. (#6532)Flags, subdivision flags, skin-tone-modified emoji, and ZWJ sequences are unchanged. Closes #6515.
A numeric TypeScript enum also carries its reverse mapping (
0to"UK") at runtime. The parser already ignored those keys, but.optionswas read straight off the enum object, so a three-member enum listed six values and three of them failed to parse. (#6542)The runtime patterns for
z.base64()andz.base64url()are the character sets, with length and padding enforced in code, so a multi-megabyte string can no longer overflow the regex stack through a composed schema. The JSON Schema output still emits the exact block forms, soz.toJSONSchema()is unchanged. (#6534, #6527)Composing
z.base64()into a template literal now checks the alphabet but not the length, which is howz.creditCard()already behaves there. The exportedz.regexes.base64urlis now the length-aware form, so it overflows on a multi-megabyte input the same wayz.regexes.base64does.z.email()opened with two lookaheads, and the second scanned the whole string before the match began. Both are gone, and the rule they enforced — no empty segment in the local part — is expressed structurally instead, soz.email()accepts and rejects exactly what it did before. Valid addresses validate roughly twice as fast. (#6573)The pattern string is user-visible, and every copy of it changes:
z.regexes.email, which has no capture groups now — neither of the two it used to expose held a usable value;issue.patternon a failedz.email(); and thepatternthatz.toJSONSchema()emits, which no longer carries a lookahead, so validators outside ECMAScript can compile it.Composing an email into a template literal also stops applying its no-consecutive-dots rule to the rest of the string.
Each check used to write its own bounds into the schema as it attached, in chain order, so a format check applied after
.min()and.max()replaced the tighter values with its own range. The converter folds the checks as a conjunction now. The order they are chained in no longer changes the output. (#6554, #6553)Runtime parsing enforced the bounds in every version. Only the emitted schema was wrong. The same fold fixes two more cases: a repeated
multipleOfkept the first divisor and dropped the rest, soz.number().multipleOf(2).multipleOf(3)emitted a schema that accepts 4, andz.string().min(8).length(5)emittedminLength: 5, widening a bound the runtime still rejected. Closes #6550.Eight members on a Zod Classic schema —
.format,.minLength,.maxLength,.minValue,.maxValue,.isInt,.minDateand.maxDate— are computed from the checks now instead of being written onto every instance at construction. Each one is a prototype getter that becomes an own property on first read. (#6554)A key is absent until something reads it, and
Object.assign({}, schema)copies only the members that have been read. Deleting one restores the getter, and the next read recomputes it.The values can move too, because the getters read the same fold the JSON Schema converter does. An order-dependent chain reports the tighter bound now instead of whichever check wrote last.
Commits
Zod 4.6 rolls up 72 commits.
661673aedocs: make the 9thCO logo visible on the light theme by @colinhacks6de10dcedocs: reconcile the sponsor listings against every active sponsorship (#6579) by @colinhacks213ee75dfeat(compile): add z.withParser for externally generated parsers (#6575) by @colinhacksf9465d4edocs: reconcile the sponsor listings with active sponsorships (#6576) by @colinhacksf7fd5548perf(v4): drop the lookaheads from the email regex (#6573) by @colinhacks36f17960fix(v4): stop the memoizer from pinning a finished parse (#6572) by @colinhacks22bed613feat(v4): add z.iban() string format with mod-97 checksum (#6571) by @colinhacksc5b9bcb3bench: measure what a runtime island's leaked indent cost the generated source by @colinhackse54716cbdocs(ecosystem): add @apical-ts/craft (#5946) by @gunzipdcbcf052fix(compile): unwind the doc indent when a child generator throws (#6570) by @colinhacks277613a6docs: move the release procedure to the maintainer-local notes by @colinhackseb1c1089ci: release only on workflow_dispatch behind the npm environment (#6569) by @colinhacks741981ffperf(compile): for-in record walk, cheaper issue finalization, and a generative compile differential (#6567) by @colinhacks804e0f52perf: seal the CommonJS exports so require("zod") stops reading through a getter (#6564) by @colinhacks6f048367fix(v4): derive JSON Schema constraints by folding checks in the converter (#6554) by @colinhackse4d67f3eMigrate development and CI to Nub (#6562) by @colinhacks7a002366fix(v4): don't let format checks overwrite tighter min/max bounds (#6553) by @colinhacks5489a532test(v4): pin the check-chain case that keeps compiled validate's definite guard (#6551) by @colinhackse7604717docs: attribute the compiled failure cost to the fallback, not the double pass by @colinhacks764ac59fperf(v4): settle z.validate on the first failure in parse order (#6544) by @colinhacks07917f4ctest(v4): pin the lazy safeParse error's stack behavior (#6548) by @colinhacks62e6624bfeat(v4): add .validate() and .validateAsync() to Zod Classic (#6547) by @colinhackscafbee47fix(v4): parse recursive schemas built by a factory (#6530) by @colinhacks4d730882Release the parsed input once a failing safeParse builds its error (#6543) by @colinhacks90269c60Keep a numeric TS enum's reverse-mapping keys out of.options(#6542) by @colinhacks18e71c71Rename the JSON Schemaprocesshelper so bundler polyfills cannot collide (#6541) by @colinhacks68aca3dcdocs: cover the 4.5 API surface that never made it into the reference by @colinhackseca96871fix(v4): enforce the six JSON Schema keywords fromJSONSchema silently dropped (#6535) by @colinhacks81ded991perf: answer z.validate from the compiled fast path on invalid input (#6538) by @colinhacks51caf010refactor: collapse cachedInternal back into cached (#6540) by @colinhacksabfb3897feat(v4): make z.properties() a schema, and give z.instanceof() a .properties() method (#6536) by @colinhacks69f2a7ffCollapse toZod's normalizer and move its docs to the API reference (#6539) by @colinhacksbf990216perf: move util.cached's accessor to a prototype (#6537) by @colinhacksbec73beaperf(v4): build the safeParse error on first read (#6519) by @colinhacks07c43e2aKeep the runtime base64 regexes linear so composed parse paths cannot overflow (#6534) by @colinhacksbc1157e7docs: use a Response example for z.properties() by @colinhacks2ec972ecrefactor: collapse toZod's enum leaf normalizer to a dummy union (#6533) by @colinhacks68a609acWiden literal inputs in property check types (#6520) by @colinhacks0227e53ddocs: bump the star pill's GitHub mark to 20px by @colinhacks84dd3b0fperf: build literal and enum pattern regexes lazily (#6531) by @colinhacksf83ab511fix(v4): reject component-only strings from z.emoji() (#6532) by @colinhacks74f9a6d3docs: drop the toZod enum block from basics and pin the page's curation rule in a comment by @colinhacksa2a019a5Accept enum-typed targets in z.toZod (#6528) by @colinhacks319f47f4Emit a length-aware base64url pattern in toJSONSchema (#6527) by @colinhacks08ba069eperf(v4): read Luhn digits with charCodeAt instead of string indexing (#6529) by @colinhacks1ec6b7c5docs: add an RSS feed to the blog at /blog/rss.xml by @colinhacksb801439bbench: add typebox (compiled and dynamic) to the moltar cross-library harness by @colinhacks7ae49d64docs: drop the circle around the star pill's GitHub mark and center it on the pill's arc by @colinhacks93f3ab32docs: replace the blog navbar's GitHub icon with a star-count pill by @colinhacksfb2fedfddocs: tighten the memory chart callout, pad the canvas, say "less memory" by @colinhacksff56a551docs: center the memory chart callout labels and pad them off the number by @colinhacks8cd1250fdocs: center the memory chart callout labels by @colinhacks3195ed01docs: label the memory chart like the compile chart by @colinhacksa6b49390Mark the compile internals @internal instead of hiding them (#6518) by @colinhacks40b4d0b3fix(ci): read zod's latest version with npm view when picking the backfill dist-tag by @colinhacks5ff95665Stop re-exporting the compile internals from zod/v4/core (#6511) by @colinhacksf412178dci: publish @zod/mini to JSR in lockstep with npm (#6510) by @colinhacksf3e7c72efix(docs): render the docs 404 page inside the (doc) layout once by @colinhacksf3cb3644docs: surface the blog on the home page and in the sidebar by @colinhackscd4f9a67perf(v4): report Standard Schema issues without constructing a ZodError (#6509) by @colinhacks43b9bfc5docs: drop the bound-methods section from the Zod package page by @colinhacks70eb2c07docs: drop the traits section and the compilation feature bullet by @colinhacks1c0bce0cdocs: bring the 4.5 charts and worked examples into the docs pages by @colinhacksa0898b4bci: wait hours for npm to serve a publish, not ten minutes (#6502) by @colinhacksc46eeff0chore: narrow blanket biome-ignore comments (#6504) by @pullfrog[bot]c7ec94d3ci: check zod and @zod/mini lockstep on npm after every publish (#6507) by @colinhacks81065739chore(docs): build with Turbopack by @colinhacksabd41adbdocs(wiki): move plans and comparisons into a gitignored internal/ (#6506) by @colinhacks2956c4c2chore(mini): sync @zod/mini to 4.5.4 by @colinhacks8ce9e8d5feat(mini): publish Zod Mini as the standalone @zod/mini package (#6491) by @colinhacks93186cabdocs(wiki): drop the zod-compiler benchmark (#6505) by @colinhacks908c9e17fix(docs): retry the GitHub stars fetch and log the real status by @colinhacksConfiguration
📅 Schedule: (in timezone UTC)
* 0-4 * * 1)🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by self-hosted Renovate.