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 zod

The 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/nuxt'

// ❌ 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/vue'

// 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

On this page