Zod
Using Zod schemas with kvant, including codecs and piping from kvantjs/schema.
kvant accepts any object with parse and encode methods, including
Zod schemas. Pass them directly to kvant wherever a schema
is expected.
Installation
npm install zodThe golden rule: never throw
Zod's .parse() throws on invalid input. That is the opposite of the
kvant schema contract, where stored values are user-editable and invalid
input must degrade gracefully.
When passing a Zod schema to kvant, make it total: either cover every
possible input, or attach a fallback with .catch().
import * as from 'zod'
import { } from 'kvantjs/react'
// ❌ Throws on ?price=abc
const [] = ('price', ..())
// ✅ Falls back to 0
const [] = ('price', ..().(0))
// ✅ Falls back to undefined (kvantjs/schema's default behavior)
const [] = ('price', ..().().())Codecs
Zod codecs are bidirectional by design, which maps naturally onto kvant's parse/encode contract without any intermediate layers:
import * as from 'zod'
import { } from 'kvantjs/react'
// Stored as an ISO string, used as a Date
const = .(
..().().(),
.().(),
{
: => != null ? new () : ,
: => ?.(),
}
)
const [, ] = ('last-visit', )See Zod docs for
more useful codecs (base64ToBytes, stringToURL, etc.). All of them work with
kvant as long as they can't throw on the inputs the desired interface can actually
contain.
Mixing kvantjs/schema and Zod
The most practical setup: let kvantjs/schema handle the storage layer
(smart casting, defaults, clear-on-default) and pipe into Zod.
import * as from 'kvantjs/schema'
import * as from 'zod'
const = .().(
.().().()
).pipe(schema) and all other built-in kvantjs/schema wrappers and combinators
accept any { parse, encode } object, not only kvant schemas.
The kvant side deals with the raw storage representation, and Zod
validates the typed result. Encoding runs in reverse through the same chain.
Be careful with this power!
Learn more
- Zod documentation
- Zod codecs
- kvantjs/schema — the built-in alternative
- Custom schema — adapting other libraries