fatline

Codecs

Type-safe serialization with Zod, Valibot, or ArkType

Codecs combine serialization with schema validation. Your schema tells fatline exactly where extended types live, so decoding is faster and type-safe.

Creating Codecs

import { createCodec } from 'fatline/codec'
import { z } from 'zod'

const UserCodec = createCodec(z.object({
  id: z.string(),
  email: z.string().email(),
  createdAt: z.date(),
  preferences: z.map(z.string(), z.unknown()),
}))

// Encode
const json = UserCodec.encode(user)

// Decode (deserialize + validate)
const user = UserCodec.decode(json)
//    ^? { id: string, email: string, createdAt: Date, preferences: Map<string, unknown> }

Decode Modes

// Standard: validates, throws on error
const user = UserCodec.decode(json)

// Unsafe: skip validation (for trusted sources)
const user = UserCodec.decodeUnsafe(json)

// Safe: returns Result, never throws
const result = UserCodec.safeDecode(json)
// { success: true, data: User } | { success: false, error: FatlineError }

// Lenient: partial success with field-level errors
const { data, errors } = UserCodec.decodeLenient(json)

Schema Fingerprinting

Each codec has a content-based hash:

UserCodec.hash  // "a3f2c1b8"

Same schema, same hash—regardless of when or where it was compiled. This lets client and server verify they're speaking the same language.

// packages/schemas/user.ts (shared)
export const UserSchema = z.object({
  id: z.string(),
  createdAt: z.date(),
})

// Server
import { createCodec } from 'fatline/codec'
const ServerCodec = createCodec(UserSchema)
ServerCodec.hash  // "a3f2c1b8"

// Client
import { createCodec } from 'fatline/codec'
const ClientCodec = createCodec(UserSchema)
ClientCodec.hash  // "a3f2c1b8"

When hashes match, you can skip validation entirely with decodeUnsafe.

Schema Registry

For managing multiple schemas:

import { createRegistry } from 'fatline/codec'

const registry = createRegistry()

const UserCodec = registry.register('User', UserSchema)
const PostCodec = registry.register('Post', PostSchema)

// Retrieve by name
const codec = registry.get('User')

// Verify schema version
registry.verify('User', 'a3f2c1b8')  // boolean

Next Steps

On this page