Zod validates but doesn't produce JSON Schema. AJV needs JSON Schema but has no TypeScript inference. TypeBox gives you both — write TypeScript types that ARE JSON Schemas.
What Is TypeBox?
TypeBox is a JSON Schema type builder that creates in-memory JSON Schemas with static TypeScript types. One definition, two outputs: runtime validation AND compile-time types.
Quick Start
npm install @sinclair/typebox
import { Type, Static } from '@sinclair/typebox';
const User = Type.Object({
id: Type.String({ format: 'uuid' }),
name: Type.String({ minLength: 2 }),
email: Type.String({ format: 'email' }),
age: Type.Optional(Type.Integer({ minimum: 0 })),
role: Type.Union([
Type.Literal('admin'),
Type.Literal('user'),
]),
});
// Static type — identical to a hand-written interface
type User = Static<typeof User>;
// { id: string; name: string; email: string; age?: number; role: 'admin' | 'user' }
// Runtime value — valid JSON Schema
console.log(User);
// { type: 'object', properties: { id: { type: 'string', format: 'uuid' }, ... } }
Validation
import { Value } from '@sinclair/typebox/value';
// Validate
const isValid = Value.Check(User, inputData); // boolean
// Parse with errors
const result = Value.Parse(User, inputData);
// Decode (coerce types)
const decoded = Value.Decode(User, rawData);
// Default values
const withDefaults = Value.Default(User, partialData);
With Fastify (Built-In)
import Fastify from 'fastify';
const app = Fastify();
app.post('/users', {
schema: {
body: User,
response: {
200: Type.Object({ id: Type.String(), success: Type.Boolean() }),
},
},
}, async (request) => {
// request.body is validated AND typed as User
const user = request.body;
return { id: '123', success: true };
});
Fastify uses TypeBox natively — zero extra config.
Common Patterns
// Arrays
const Tags = Type.Array(Type.String(), { minItems: 1 });
// Records (dynamic keys)
const Config = Type.Record(Type.String(), Type.Unknown());
// Intersections
const TimestampedUser = Type.Intersect([
User,
Type.Object({
createdAt: Type.String({ format: 'date-time' }),
updatedAt: Type.String({ format: 'date-time' }),
}),
]);
// Recursive types
const TreeNode = Type.Recursive((This) =>
Type.Object({
value: Type.String(),
children: Type.Array(This),
})
);
// Pick/Omit
const UserCreate = Type.Omit(User, ['id']);
const UserPreview = Type.Pick(User, ['id', 'name']);
Why TypeBox
| Feature | TypeBox | Zod | JSON Schema |
|---|---|---|---|
| TypeScript types | Auto-inferred | Auto-inferred | Manual |
| JSON Schema output | Native | Plugin | Native |
| Fastify integration | Built-in | Plugin | Built-in |
| OpenAPI compatible | Yes | Plugin | Yes |
| Bundle size | 30KB | 57KB | Varies |
| Validation speed | Very fast (AJV) | Fast | Very fast |
Get Started
- GitHub — 5K+ stars
- Documentation
Validating API data? My Apify scrapers produce JSON Schema-compatible outputs. Custom solutions: spinov001@gmail.com
Top comments (0)