Colin McDonnell 💎 Zod
@colinhacks.com
4.9K followers 220 following 170 posts
💎 Creator of Zod, tRPC (v0) 🔮 OSS Fellow @ Clerk 🦆 Friendly neighborhood TypeScript nerd 🧑🏼‍💻 Prev @ Bun, EdgeDB, YC, MIT
Posts Media Videos Starter Packs
colinhacks.com
as you said, "decode" and "parse" are essentially synonymous. encoding is the new thing here, and it's the inverse of parse. but in anycase, this isn't something I just came up with: see io-ts and Effect Schema.
colinhacks.com
for a more detailed technical breakdown of codecs, read the associated blog post 👍 colinhacks.com/essays/intro...
Introducing Zod Codecs
colinhacks.com
colinhacks.com
including...

✅ stringToNumber
✅ stringToInt
✅ stringToBigInt
✅ numberToBigInt
✅ isoDatetimeToDate
✅ epochSecondsToDate
✅ epochMillisToDate
✅ jsonCodec
✅ utf8ToBytes
✅ bytesToUtf8
✅ base64ToBytes
✅ base64urlToBytes
✅ hexToBytes
✅ stringToURL
✅ uriComponent
colinhacks.com
instead of providing first-party APIs for commonly-needed codecs, Zod is taking a page from shadcn

fully-tested versions of 16 commonly-needed codecs are available on the new Codecs page. you're encouraged to copy/paste/customize them as needed 👍
zod.dev/codecs
Codecs | Zod
Bidirectional transformations with encode and decode
zod.dev
colinhacks.com
Codecs is useful when mapping data between two different domains. for instance, when converting data in your Node.js backend from a rich JavaScript representation (Dates, BigInts, Maps, Sets, etc) into a JSON-serializable format (ISO datetimes, arrays, etc)
colinhacks.com
these methods are intended for use cases involving data *conversion*, not *validation* (though they do that too). so if you pass in an input of an unexpected type, you'll get a TypeScript error.
colinhacks.com
"how does .decode() differ from .parse()?"

good question! they're identical at runtime, but their type signatures differ in an important way.

unlike .parse()—which accepts `unknown` input—decode and encode expect strongly-typed inputs
colinhacks.com
It is coupled with the addition of new methods (available on all Zod schemas)

.decode() — "forward" parsing
.encode() — "reverse" parsing
colinhacks.com
Introducing Zod 4.1 and its flagship feature: codecs.

z.codec() is a new API for defining *bi-directional transformations* in Zod
colinhacks.com
in the absence of an existing convention, I'm adding these three fields to Zod's package.json.

making this stuff auto-discoverable would resolve one of the biggest usability issues with today's agents/IDEs. a simple convention here will go a long way! 🤘
colinhacks.com
sounds like you found an alternative but the answer is "not at all". MIT license, go ham :)
colinhacks.com
Zod 4 stable will be released this Monday, May 19th!
colinhacks.com
hi Axel! big fan! the ? syntax definitely felt right...and when it unlocked recursive objects I knew it was the way.

though actually in Zod 4, z.object() adds the "?"to T.optional() but not to z.union(T, z.undefined()) as you're suggesting...a small change that makes things a little more sound
colinhacks.com
z.safeint() exists but it's just z.int() 🙃 anything outside of safe range will throw. hadn't considered doubleint seriously. is that basically z.int128()? I'd represent that with a ZodBigInt subclass (similar to z.int64() and z.uint64 currently). but idk if it's widely used enough to merit addition?
colinhacks.com
yikes, thanks! last minute changes gone awry
colinhacks.com
thank you! this means a lot and is exactly the reaction I was hoping for :))))
colinhacks.com
huge thanks to @clerk.com for supporting my work on Zod 4! they've been an amazing partner through the much-longer-than-expected development process 🫶
colinhacks.com
the beta period will last 4-6 weeks so ecosystem tooling/library authors can implement day-one support. if that's you: this page is a good starting point. don’t hesitate to reach out for guidance!
v4.zod.dev/packages/core
@zod/core | Zod Docs
v4.zod.dev
colinhacks.com
breakage was kept to an absolute minimum, but there are some relatively minor changes to the public API. i'd love for some brave pioneers to upgrade and report any breakage not described in the changelog:
v4.zod.dev/v4/changelog
Migration guide | Zod Docs
v4.zod.dev
colinhacks.com
Zod 4 is now in beta!

💎 7x faster object parsing
💎 20x reduction in tsc instantiations
💎 57% smaller core bundle size
💎 metadata via .meta()
💎 z.toJSONSchema()
💎 z.templateLiteral()
💎 z.stringbool()
💎 z.int32(), z.float32(), etc
💎 z.file()
💎 new logo 😇
Introducing Zod 4 beta | Zod Docs
v4.zod.dev
colinhacks.com
if I may be so bold, I'd like to propose some much-needed nomenclature