DEV Community

Alex Spinov
Alex Spinov

Posted on

TypeBox Has a Free JSON Schema Type Builder — Here's How to Use It

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
Enter fullscreen mode Exit fullscreen mode
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' }, ... } }
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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 };
});
Enter fullscreen mode Exit fullscreen mode

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']);
Enter fullscreen mode Exit fullscreen mode

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


Validating API data? My Apify scrapers produce JSON Schema-compatible outputs. Custom solutions: spinov001@gmail.com

Top comments (0)