A few weeks ago I released a TypeScript library called @traversable/zod.
This post covers what the library does, and highlights a few of its unique features.
Note:
Currently @traversable/zod only works with the latest version of Zod (v4).Cover photo credit:
Jack Noble, Mob Psycho 100 モブサイコ100
What makes @traversable/zod different?
@traversable/zod can be used in 2 ways:
- Pick one of over 25 transformers available off-the-shelf
- Hand-roll your own custom transformer
Off-the-shelf
ᯓ📦 zx.check
Converts a Zod schema into a super-performant type-guard
ᯓ📦 zx.deepClone
Converts a Zod schema into a "deep copy" function
ᯓ📦 zx.deepEqual
Converts a Zod schema into a "deep equal" function
ᯓ📦 zx.deepPartial
Makes all the properties of a Zod schema optional
ᯓ📦 zx.toString
Converts a Zod schema into a string
Useful for testing, codegen, sanity checking
ᯓ📦 zx.toType
Converts a Zod schema into a TypeScript type
Preserves schema metadata as JSDoc annotations
ᯓ📦 zx.makeLens
🔍 Focus nested values with lenses (getters/setters)
🌈 Reify control flow with prisms (pattern-matchers)
⛰️ Map over containers with traversals (for-loops)
🧱 Stack them together with function composition
Roll your own
ᯓ📦 zx.fold
All the off-the-shelf transformers that @traversable/zod ships are powered by zx.fold
.
Under the hood, the library uses an abstraction called recursion schemes that make implementing recursion simple and fun.
To demonstrate, I used it to implement toJsonSchema
.
The implementation is so minimal (28 lines!) that I've embedded it here, in its entirety:
Note:
I specifically chose
toJsonSchema
because multiple libraries already exist that do this, including Zod itself.The goal is to showcase how you can use
zx.fold
to build a library of your own.
Closing thoughts
Thanks for reading!
If you have any feedback, feature requests, or questions, feel free to open an issue or start a discussion.
Links
- @traversable/zod on GitHub
- The full
toJsonSchema
demo
Top comments (6)
Good stuff
Thanks for reading!
Nice Article Andrew!
Thanks!
Looks cool, but sandbox steals my input focus is annoying
Ack! I don't know how to fix this. Might just rip it out and use a code block