@vertz/schema is the validation layer used across the entire stack — entity inputs, form validation, action bodies, and custom checks. Define a schema once with the s builder, get TypeScript types automatically, and validate at runtime with structured errors.
The s builder
Every schema is immutable — methods return new instances, never mutate.
Primitives
Built-in format schemas that validate structure, not just type:
Objects
Composition
Arrays, tuples, and collections
Enums and literals
Unions
String constraints
Number constraints
Modifiers
These work on any schema:
Refinements
For validation logic that goes beyond built-in constraints:
Change the output type:
Coercion
Convert types before validation:
Type branding
Prevent mixing values that share a primitive type:
Validation
safeParse — errors as values
Returns a Result — never throws:
parse — throws on failure
For cases where you want exceptions (scripts, tests):
safeParse is the recommended approach — it aligns with Vertz’s errors-as-values philosophy. Use
parse only in contexts where throwing is acceptable (test setup, scripts).
Validation issues
Every validation error includes structured issue objects:
Errors accumulate — all issues are reported, not just the first one.
Type inference
Extract TypeScript types from schemas:
When transforms change the type, Input and Output differ:
Where schemas are used
| Context | How it’s used |
|---|
| Entity custom actions | body defines the input schema, validated before the handler runs |
| Services | Same — body schema validates request input |
Forms (form()) | Schema drives client-side validation and field error messages |
| DB column bridge | s.fromDbEnum(column) converts database enum columns to schemas |