Schema
Always-on. Lightweight typing scaffold. Source of truth:
packages/hub/src/kernel/schema.ts
noy-db stores typed records in collections inside an encrypted vault. Schema is the always-on core feature that keeps those records well-shaped: attach any Standard Schema v1 validator (Zod, Valibot, ArkType, Effect Schema, …) to a collection via collection(name, { schema }). Input is validated on put() before encryption; output is validated after decryption on read.
For typed relationships between collections — foreign keys, integrity, joins — see Foreign refs.
Schema validation
Pass a Standard Schema validator when creating the collection:
import { z } from 'zod'
import { createNoydb } from '@noy-db/hub'
const InvoiceSchema = z.object({
id: z.string(),
amount: z.number().positive(),
status: z.enum(['draft', 'open', 'paid', 'overdue']),
date: z.string().datetime(),
})
const db = await createNoydb({ user: 'alice', secret: '…' })
const vault = await db.openVault('acme')
const invoices = vault.collection<z.infer<typeof InvoiceSchema>>('invoices', {
schema: InvoiceSchema,
})
await invoices.put('inv-1', { id: 'inv-1', amount: 120, status: 'open', date: '2026-07-01T00:00:00Z' })
// → stored (encrypted) — the validated value is what gets persisted
await invoices.put('inv-2', { id: 'inv-2', amount: -5, status: 'open', date: '2026-07-01T00:00:00Z' })
// → throws SchemaValidationError: "Schema validation failed on put(inv-2): amount: …"
- Input validation runs in
put()before encryption. A rejected record throwsSchemaValidationErrorwithdirection: 'input'and the validator's full structuredissueslist — useful for rendering field-level messages in a UI. - Output validation runs on records coming out of
get()/list()/query()after decryption. If stored data has drifted from the current schema, it throws withdirection: 'output'instead of silently returning garbage. - Validators may transform the input (coerce strings to numbers, strip unknown fields); the transformed value is what gets encrypted and stored.
The T parameter on Collection<T> is the validator's output type — whatever it produces after coercion and transforms. The InferOutput<typeof schema> helper type (exported from @noy-db/hub) derives it from a schema instance.
Edge cases
- Schema validation is opt-in per collection; a vault can mix validated and unvalidated collections.
- When a collection also declares
i18nTextfields (see i18n), the schema validates first; the i18n required-translation check runs after it, on the schema-validated record.
See also
- Foreign refs — typed references between collections
- Core 01 — Vault & Collection model
- i18n —
i18nText/dictKeyfield descriptors layered on top