JSON Schema Type Builder with Static Type Resolution for TypeScript

$ npm install typebox
import Type from 'typebox'
const T = Type.Object({ // const T = {
x: Type.Number(), // type: 'object',
y: Type.Number(), // properties: {
z: Type.Number() // x: { type: 'number' },
}) // y: { type: 'number' },
// z: { type: 'number' }
// },
// required: ['x', 'y', 'z']
// }
type T = Type.Static<typeof T> // type T = {
// x: number,
// y: number,
// z: number
// }
TypeBox is a runtime type system that creates in-memory JSON Schema objects that infer as TypeScript types. The schematics produced by this library are designed to match the static type checking rules of the TypeScript compiler. TypeBox offers a unified type that can be statically checked by TypeScript and runtime checked using standard JSON Schema validation.
This library is designed to allow JSON Schema to compose similar to how types compose within TypeScript's type system. It can be used as a simple tool to build up complex schematics or integrated into REST and RPC services to help validate data received over the wire.
License: MIT
TypeBox types are JSON Schema fragments that compose into more complex types. The library offers a set of types used to construct JSON Schema compliant schematics as well as a set of extended types used to model constructs native to the JavaScript language. The schematics produced by TypeBox can be passed directly to any JSON Schema compliant validator.
The following creates a User type and infers with Static.
import Type from 'typebox'
// Type
const User = Type.Object({ // const User = {
id: Type.String(), // type: 'object',
name: Type.String(), // properties: {
email: Type.String({ format: 'email' }) // id: { type: 'string' },
}) // name: { type: 'string' },
// email: {
// type: 'string',
// format: 'email'
// }
// }
// required: [
// 'id',
// 'name',
// 'email'
// ]
// }
// Static
type User = Type.Static<typeof User> // type User = {
// id: string,
// name: string,
// email: string
// }
Documentation | Example 1 | Example 2 | Challenge
TypeBox includes a syntax engine that can transform TypeScript declarations into JSON Schema. The engine is a full syntactic frontend to Type.* and supports many advanced type-level constructs such as Conditional, Mapped, Indexed, Infer, Generics, Distributed types and more. This feature is implemented symmetrically at runtime and statically via TypeScript Template Literal types.
Syntax highlighting is available via the Visual Studio Marketplace
The following uses Script to parse TypeScript declarations into JSON Schema.
// Module
const Math = Type.Script(`
type Vector2 = { x: number, y: number }
type Vector3 = Evaluate<Vector2 & { z: number }>
type Vector4 = Evaluate<Vector3 & { w: number }>
`)
// Dependent Module
const { Mesh } = Type.Script({ ...Math }, `
type Vertex = {
position: Vector4,
normal: Vector3,
uv: Vector2
}
type Geometry = {
vertices: Vertex[],
indices: number[]
}
type Material = {
ambient: Vector4,
diffuse: Vector4,
specular: Vector4
}
type Mesh = {
geometry: Geometry,
material: Material
}
`)
// Runtime Reflection
Mesh.properties.geometry.properties.vertices.items.properties.position.properties.x
Mesh.properties.geometry.properties.vertices.items.properties.normal.properties.x
Mesh.properties.geometry.properties.vertices.items.properties.uv.properties.x
Mesh.properties.material.properties.diffuse.properties.x
Mesh.properties.material.properties.ambient.properties.x
Mesh.properties.material.properties.specular.properties.x
// Static Inference
function render(mesh: Type.Static<typeof Mesh>) {
mesh.geometry.vertices[0].position.x
mesh.geometry.vertices[0].normal.x
mesh.geometry.vertices[0].uv.x
mesh.material.diffuse.x
mesh.material.ambient.x
mesh.material.specular.x
}
Documentation | Example 1 | Example 2
TypeBox includes a high-performance JIT compiler that supports JSON Schema Draft 3 through to 2020-12. It is designed to be a lightweight industry-grade alternative to Ajv and offers improved compilation and validation performance. It also provides automatic fallback to dynamic validation in JIT restricted environments such as Cloudflare Workers.
The compiler is available via optional sub module import.
import Schema from 'typebox/schema'
The compiler accepts JSON Schema and returns Validator instances.
const Vector = Schema.Compile(Type.Object({ // const Vector: Validator<TObject<{
x: Type.Number(), // x: TNumber
y: Type.Number(), // y: TNumber
z: Type.Number() // z: TNumber
})) // }>>
With JSON Schema
const Vector = Schema.Compile({ // const Vector: Validator<{
type: 'object', // type: "object";
required: ['x', 'y', 'z'], // required: ["x", "y", "z"];
properties: { // properties: { ... };
x: { type: 'number' }, // }, { ... }>
y: { type: 'number' },
z: { type: 'number' }
}
})
Validator instances provide functions to Check and Parse values.
const Vector = Schema.Compile(Type.Script(`{
x: number
y: number
z: number
}`))
const valid = Vector.Check({ // const valid: boolean
x: 1,
y: 0,
z: 0
})
const value = Vector.Parse({ // const value: {
x: 1, // x: number
y: 0, // y: number
z: 0 // z: number
}) // }
The following table shows specification coverage implemented by TypeBox.
| Spec | 3 | 4 | 6 | 7 | 2019-09 | 2020-12 | v1 |
|---|---|---|---|---|---|---|---|
| additionalItems | ✅ | ✅ | ✅ | ✅ | ✅ | - | - |
| additionalProperties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| allOf | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| anchor | - | - | - | - | ✅ | ✅ | ✅ |
| anyOf | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| boolean_schema | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| const | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| contains | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| content | - | - | - | - | ✅ | ✅ | ✅ |
| default | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| dependencies | 17/18 | ✅ | ✅ | ✅ | - | - | - |
| dependentRequired | - | - | - | - | ✅ | ✅ | ✅ |
| dependentSchemas | - | - | - | - | ✅ | ✅ | ✅ |
| dynamicRef | - | - | - | - | - | 38/44 | 19/27 |
| enum | 14/16 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| exclusiveMaximum | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| exclusiveMinimum | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| if-then-else | - | - | - | ✅ | ✅ | ✅ | ✅ |
| infinite-loop-detection | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| items | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| maxContains | - | - | - | - | ✅ | ✅ | ✅ |
| maximum | 13/14 | 13/14 | ✅ | ✅ | ✅ | ✅ | ✅ |
| maxItems | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| maxLength | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| maxProperties | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| minContains | - | - | - | - | ✅ | ✅ | ✅ |
| minimum | 12/13 | 16/17 | ✅ | ✅ | ✅ | ✅ | ✅ |
| minItems | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| minLength | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| minPro |
$ claude mcp add typebox \
-- python -m otcore.mcp_server <graph>