Baobox keeps the TypeBox-style builder APIs, but it also supports a TypeScript-like DSL, named definition modules, and runtime registries for project-specific validation.
Use Script() when the schema is easier to read as a compact type expression.
import { Check, Script } from 'baobox'
const Users = Script('Array<{ name: string; age?: number }>')
Check(Users, [{ name: 'Ada' }, { name: 'Grace', age: 37 }])
// trueFor reusable named definitions, use ScriptWithDefinitions().
import { Check, Object, ScriptWithDefinitions, String } from 'baobox'
const User = Object({ name: String() }, { required: ['name'] })
const Users = ScriptWithDefinitions('Array<User>', { User })
Check(Users, [{ name: 'Ada' }])
// trueUse Module() when you want a small schema registry with named definitions, then resolve a concrete definition with Import().
import { Check, Import, Module, Object, String } from 'baobox'
const Models = Module({
User: Object({
id: String(),
name: String(),
}, { required: ['id', 'name'] }),
})
const User = Import(Models, 'User')
Check(User, { id: 'usr_1', name: 'Ada' })
// truemodule.Import(name) returns a Ref schema. Import(module, name) returns the concrete definition directly.
Use the format registry for new string formats.
import { Check, FormatRegistry, String } from 'baobox'
FormatRegistry.Set('doc-slug', (value) => /^[a-z0-9-]+$/.test(value))
const Slug = String({ format: 'doc-slug' })
Check(Slug, 'docs-ready')
// trueUse the type registry for custom ~kind validators.
import { Check, TypeRegistry, type TSchema } from 'baobox'
TypeRegistry.Set('PositiveNumber', (_schema, value) =>
typeof value === 'number' && value > 0
)
const PositiveNumber: TSchema = { '~kind': 'PositiveNumber' }
Check(PositiveNumber, 3)
// trueRegistry notes:
- Keep custom names stable. They become part of your schema contract.
- Clean up temporary test-only registrations with
Delete(). TypeRegistryaffects runtime validation. It does not add JSON Schema emission automatically.
Use Codec() when you want typed decode and encode transforms without writing callback casts.
import { Codec, String } from 'baobox'
import { Decode, Encode } from 'baobox/value'
const Trimmed = Codec(String())
.Decode((value) => value.trim())
.Encode((value) => value.toUpperCase())
Decode(Trimmed, ' ada ')
// "ada"
Encode(Trimmed, 'ada')
// "ADA"