What it is
TypeBox builds JSON Schema objects that also carry TypeScript types, so one definition serves runtime validation, static typing and OpenAPI documentation.
Type.Object and friends emit real JSON Schema. Validation runs through a JSON Schema validator such as Ajv, or TypeBox's own compiler for higher throughput.
Installation
npm install @sinclair/typeboxGetting started
The smallest useful thing you can do with it, and what each part means.
import { Type, type Static } from '@sinclair/typebox';
const User = Type.Object({
id: Type.Integer({ minimum: 1 }),
email: Type.String({ format: 'email' }),
role: Type.Union([Type.Literal('admin'), Type.Literal('member')]),
});
type User = Static<typeof User>;
// `User` is a plain JSON Schema object — publishable as OpenAPI directly.
console.log(JSON.stringify(User, null, 2));import { TypeCompiler } from '@sinclair/typebox/compiler';
// Compile once at startup — this generates specialised checking code.
const check = TypeCompiler.Compile(User);
if (!check.Check(input)) {
const errors = [...check.Errors(input)];
throw new Error(errors[0].message);
}
// input is narrowed to User hereAdvanced usage
Where the library earns its place over a simpler alternative.
// Fastify uses JSON Schema natively, so TypeBox needs no adapter.
fastify.post('/users', {
schema: {
body: User,
response: { 201: User },
},
}, async (request, reply) => {
// request.body is typed as User and already validated by Fastify
return reply.code(201).send(await store.create(request.body));
});Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- Validation passes but the data is wrong
- JSON Schema ignores unknown keys by default. Add additionalProperties: false to the object options.
- format: 'email' is not enforced
- Formats are annotations; Ajv needs ajv-formats registered to actually check them.
Best practices
- Compile schemas once at startup with TypeCompiler; compiling per request throws away the benefit.
- Choose TypeBox when the schema must also serve OpenAPI or a non-TypeScript consumer.
- Use Type.Optional rather than Type.Union with undefined for optional fields.
- Remember that TypeBox describes shape, not business rules — those still need explicit checks.
Background
Why it exists, and what it was reacting to.
Created by Haydn Paterson, TypeBox differs from Zod in producing standards-compliant JSON Schema rather than a proprietary structure — which matters when the schema must also be consumed by tools outside TypeScript.
