Type-safe validation for TypeScript
Elegant and battle-tested validation library that provides runtime type checking with automatic TypeScript type inference
import { object, string, number, array } from 'decoders';
const userDecoder = object({
id: number,
name: string,
tags: array(string),
});
const user = userDecoder.verify(externalData);
// ^? { id: number; name: string; tags: string[] }
Why decoders?
Build robust TypeScript applications with confidence using validation that catches errors at runtime
Type inference
Automatic TypeScript type inference from your decoder definitions
Composable
Build complex validators from simple, reusable building blocks
Zero dependencies
Tiny bundle size with zero runtime dependencies and full tree-shaking support
Excellent errors
Detailed error messages that pinpoint exactly what went wrong
Battle-tested
Used in production by thousands of projects with comprehensive test coverage
Cross-platform
Works everywhere: Node.js, browsers, Bun, Deno, and Cloudflare Workers
Quick start
Get up and running with decoders in minutes
Install the package
Install decoders using your preferred package manager:Make sure you have "strict": true in your tsconfig.json for proper type inference.
Import and create a decoder
Define your data structure using decoder functions:import { object, string, number, optional, array } from 'decoders';
const userDecoder = object({
id: number,
name: string,
email: optional(string),
roles: array(string),
});
The decoder describes the shape and types of the data you expect. Validate untrusted data
Use .verify() to validate data and get type-safe results:// Data from external source (API, user input, etc.)
const externalData = {
id: 123,
name: 'Alice',
roles: ['admin', 'user'],
};
// Validate and get type-safe result
const user = userDecoder.verify(externalData);
// TypeScript knows: { id: number; name: string; email?: string; roles: string[] }
console.log(user.name); // 'Alice'
If validation fails, .verify() throws an error with a detailed message. Handle validation errors
For non-throwing validation, use .decode() to get a result object:const result = userDecoder.decode(externalData);
if (result.ok) {
console.log('Valid user:', result.value);
} else {
console.error('Validation failed:', result.error);
}
The result object follows a discriminated union pattern for safe error handling.
Explore by topic
Deep dive into specific features and use cases
Resources
Additional resources to help you get the most out of decoders
GitHub repository
View the source code, report issues, and contribute to the project
Migration guide
Upgrading from v1? Learn how to migrate your existing code to v2
Ready to build type-safe applications?
Get started with decoders and add runtime validation to your TypeScript projects today