Add `z.fromJSONSchema()`, `z.looseRecord()`,`z.xor()`
- Initial version of z.fromJSONSchema
- Add z.fromJSONSchema
cc @pullfrog
Review complete! I've analyzed the implementation of fromJSONSchema() and looseRecord().
Summary:
- ✅ All tests pass (84 tests)
- ✅ Build succeeds
- ✅ Core functionality works correctly
- ⚠️ 14 issues identified (see review comments)
Main concerns:
- PR title mentions
z.xor()but it's not implemented (it's actuallyz.union([...], { exclusive: true })) - Several unrelated files included (play.ts, zod-locale.ts, zod-string.ts)
- Type safety issues with
as anycasts - Potential bug with overlapping patternProperties
- Poor error messages for tuple length validation
The implementation is solid overall, but needs cleanup and bug fixes before merging.

cc @coderabbitai review this
@colinhacks: I'll review the changes for you!
✅ Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
[!NOTE]
Other AI code review bot(s) detected
CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.
Walkthrough
This pull request introduces several new features and refinements to Zod. A new fromJSONSchema function enables converting JSON Schema definitions to Zod types with support for references, composite keywords, and constraints. A new looseRecord API allows record validation to pass through non-matching keys unchanged. Union handling gains an exclusive option for stricter disjunction validation. Export paths are reorganized for toJSONSchema and fromJSONSchema to use dedicated modules. Invalid union error types are refactored into a discriminated union distinguishing no-match from multiple-match scenarios. Record definitions now support a mode field controlling key validation behavior. Comprehensive documentation and test suites cover the new functionality.
Pre-merge checks
❌ Failed checks (2 warnings)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Description check | ⚠️ Warning | The description only mentions z.fromJSONSchema and omits z.looseRecord and exclusive union changes, making it incomplete relative to the changeset. | Expand the description to include z.looseRecord() and the exclusive union feature (xor/inclusive flag) for clarity. |
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (1 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The title accurately summarizes the three main features added: fromJSONSchema conversion function, looseRecord variant, and exclusive union (xor) support. |
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
cc @pullfrog review with a focus on the XOR stuff
✅ Review Complete - XOR Implementation Focus
Reviewed the PR with specific attention to the XOR functionality as requested. Here's what I found:
XOR Implementation (z.xor())
- ✅ Core logic is solid - correctly evaluates all options to detect multiple matches
- ✅ Good separation of concerns with
handleExclusiveUnionResultshelper - ✅ Proper error handling distinguishing zero matches vs multiple matches via
inclusive: false - 💡 Suggested adding comments explaining why XOR can't early-return like regular unions
JSON Schema Integration
- ✅ Correctly maps JSON Schema
oneOftoz.xor() - ✅ Proper handling of intersection when combined with explicit types
- ✅ Pattern matching correctly preserves JSON Schema semantics (not implicitly anchored)
Documentation & Tests
- ✅ Clear examples in api.mdx showing both success and failure cases
- ✅ Good test coverage including edge cases
- 💡 Suggested showing error messages in docs to help users debug XOR failures
Overall: The XOR implementation is well-designed and correctly implements exclusive union semantics. The integration with fromJSONSchema properly maps JSON Schema's oneOf behavior. No blocking issues found.

The release notes use xor() without an array:
z.xor(
z.object({ type: "user", name: z.string() }),
z.object({ type: "admin", role: z.string() })
)
...whicha appears to be an error?