Top Related Projects
Runtime validation for static types
TypeScript-first schema validation with static type inference
A simple and composable way to validate data in JavaScript (and TypeScript).
Dead simple Object schema validation
Decorator-based property validation for classes.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
Quick Overview
io-ts is a TypeScript library for runtime type checking and validation. It allows developers to define runtime types that correspond to TypeScript static types, enabling robust validation of data structures at runtime while maintaining type safety during development.
Pros
- Seamless integration with TypeScript, providing runtime type checking that aligns with static types
- Powerful and flexible type combinators for creating complex data structures
- Excellent error reporting, making it easier to debug and handle validation failures
- Supports custom types and codecs for advanced use cases
Cons
- Steep learning curve for developers new to functional programming concepts
- Can add complexity to simple projects where basic type checking might suffice
- Performance overhead for large, complex data structures due to runtime validation
- Limited built-in support for certain common data types (e.g., dates)
Code Examples
- Defining a simple type:
import * as t from 'io-ts'
const User = t.type({
id: t.number,
name: t.string,
email: t.string
})
type User = t.TypeOf<typeof User>
- Validating data:
import { isRight } from 'fp-ts/Either'
const data = { id: 1, name: 'John Doe', email: 'john@example.com' }
const result = User.decode(data)
if (isRight(result)) {
console.log('Valid user:', result.right)
} else {
console.error('Invalid user:', result.left)
}
- Using custom types:
const Email = new t.Type<string, string, unknown>(
'Email',
(u): u is string => typeof u === 'string',
(u, c) => {
const s = t.string.validate(u, c)
if (isLeft(s)) return s
const email = s.right
return email.includes('@') ? t.success(email) : t.failure(u, c)
},
t.identity
)
const UserWithEmail = t.type({
id: t.number,
name: t.string,
email: Email
})
Getting Started
To start using io-ts in your TypeScript project:
-
Install the required packages:
npm install io-ts fp-ts
-
Import and use io-ts in your code:
import * as t from 'io-ts' import { isRight } from 'fp-ts/Either' const MyType = t.type({ // Define your type here }) const data = // Your data to validate const result = MyType.decode(data) if (isRight(result)) { // Data is valid } else { // Handle validation errors }
Competitor Comparisons
Runtime validation for static types
Pros of runtypes
- Simpler API with less boilerplate code
- Better performance in runtime type checking
- More intuitive error messages for failed validations
Cons of runtypes
- Less extensive type inference capabilities
- Fewer built-in types and combinators
- Limited support for complex recursive types
Code Comparison
runtypes:
import { Record, String, Number } from 'runtypes';
const Person = Record({
name: String,
age: Number,
});
const person = Person.check({ name: 'Alice', age: 30 });
io-ts:
import * as t from 'io-ts';
const Person = t.type({
name: t.string,
age: t.number,
});
const person = Person.decode({ name: 'Alice', age: 30 }).getOrElse(null);
Both libraries provide runtime type checking for TypeScript, but runtypes offers a more straightforward API with less verbose syntax. io-ts, on the other hand, provides more advanced features like type refinements and custom type definitions.
runtypes focuses on simplicity and performance, making it easier to use for basic type checking scenarios. io-ts offers more flexibility and power for complex type validations, albeit with a steeper learning curve.
Choose runtypes for simpler projects with straightforward type checking needs, while io-ts might be preferable for larger applications requiring advanced type validations and transformations.
TypeScript-first schema validation with static type inference
Pros of Zod
- Simpler API and more intuitive syntax
- Better TypeScript integration with automatic type inference
- Supports asynchronous validation out of the box
Cons of Zod
- Larger bundle size compared to io-ts
- Less flexible for advanced use cases and custom types
Code Comparison
io-ts:
import * as t from 'io-ts'
const Person = t.type({
name: t.string,
age: t.number
})
const result = Person.decode({ name: 'Alice', age: 30 })
Zod:
import { z } from 'zod'
const Person = z.object({
name: z.string(),
age: z.number()
})
const result = Person.parse({ name: 'Alice', age: 30 })
Both io-ts and Zod are popular libraries for runtime type checking and validation in TypeScript. io-ts offers a more functional programming approach with its codec-based system, while Zod provides a more straightforward and user-friendly API. Zod's automatic type inference and built-in async validation make it attractive for many developers, but io-ts may be preferred for more complex scenarios or when a smaller bundle size is crucial. The choice between the two often depends on the specific project requirements and developer preferences.
A simple and composable way to validate data in JavaScript (and TypeScript).
Pros of Superstruct
- Simpler API and more intuitive syntax for defining schemas
- Better performance in runtime type checking
- Supports custom error messages and more flexible error handling
Cons of Superstruct
- Less powerful type inference capabilities
- Lacks some advanced features like branded types and opaque types
- Not as well-integrated with the TypeScript ecosystem
Code Comparison
Superstruct:
import { object, string, number, array } from 'superstruct'
const User = object({
name: string(),
age: number(),
email: string(),
friends: array(string())
})
io-ts:
import * as t from 'io-ts'
const User = t.type({
name: t.string,
age: t.number,
email: t.string,
friends: t.array(t.string)
})
Both libraries allow for runtime type checking and validation, but Superstruct's syntax is generally considered more straightforward. io-ts, on the other hand, provides stronger type inference and integration with TypeScript's type system.
Superstruct is often preferred for its simplicity and performance, making it a good choice for projects where ease of use is prioritized. io-ts shines in scenarios where advanced type-level programming and strict type safety are crucial, especially in larger TypeScript projects.
Dead simple Object schema validation
Pros of yup
- More straightforward API, easier for beginners to pick up
- Built-in support for schema validation in popular form libraries like Formik
- Extensive set of built-in validation methods
Cons of yup
- Less type-safe compared to io-ts, as it relies more on runtime checks
- Limited support for complex data structures and custom types
- Slightly larger bundle size
Code Comparison
yup:
import * as yup from 'yup';
const schema = yup.object().shape({
name: yup.string().required(),
age: yup.number().positive().integer().required(),
});
io-ts:
import * as t from 'io-ts';
const Person = t.type({
name: t.string,
age: t.number,
});
Summary
yup is more user-friendly and integrates well with form libraries, making it a popular choice for web developers. It offers a wide range of built-in validation methods but sacrifices some type safety.
io-ts, on the other hand, provides stronger type guarantees and better support for complex data structures. It's more suitable for TypeScript projects that require strict type checking and runtime validation.
The choice between the two depends on the project's requirements, the team's familiarity with functional programming concepts, and the desired level of type safety.
Decorator-based property validation for classes.
Pros of class-validator
- Simpler syntax and easier to use for basic validation scenarios
- Decorators provide a clean, declarative way to define validation rules
- Integrates well with popular frameworks like NestJS and TypeORM
Cons of class-validator
- Less powerful for complex validation scenarios compared to io-ts
- Runtime validation only, doesn't provide compile-time type safety
- Relies on decorators, which may not be suitable for all project structures
Code Comparison
class-validator:
import { IsString, IsInt, Min, Max } from 'class-validator';
class User {
@IsString()
name: string;
@IsInt()
@Min(0)
@Max(120)
age: number;
}
io-ts:
import * as t from 'io-ts';
const User = t.type({
name: t.string,
age: t.refinement(t.number, n => n >= 0 && n <= 120, 'ValidAge'),
});
type User = t.TypeOf<typeof User>;
Summary
class-validator offers a more straightforward approach for basic validation scenarios, using decorators to define rules. It integrates well with popular frameworks but lacks compile-time type safety. io-ts, on the other hand, provides more powerful validation capabilities and compile-time type safety, but with a steeper learning curve and more complex syntax for advanced scenarios.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
Pros of TypeScript
- Broader adoption and larger community support
- More comprehensive language features and tooling
- Native integration with JavaScript ecosystems
Cons of TypeScript
- Steeper learning curve for beginners
- Potentially more complex setup and configuration
- Less focused on runtime type checking
Code Comparison
TypeScript:
interface User {
name: string;
age: number;
}
const user: User = { name: "John", age: 30 };
io-ts:
import * as t from 'io-ts';
const User = t.type({
name: t.string,
age: t.number
});
const user = User.decode({ name: "John", age: 30 });
Key Differences
- TypeScript focuses on static type checking during development
- io-ts provides runtime type validation and decoding
- io-ts is built on top of TypeScript, offering additional runtime safety
- TypeScript has a more extensive type system and language features
- io-ts is specifically designed for runtime type checking and validation
Use Cases
- TypeScript: Large-scale applications, complex type systems, static analysis
- io-ts: API integrations, data validation, runtime type safety in TypeScript projects
Both tools can be used together in projects requiring both static and runtime type checking.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Installation
To install the stable version
npm i io-ts fp-ts
Note. fp-ts
is a peer dependency for io-ts
Usage
Stable features
Experimental modules (version 2.2+
)
Experimental modules (*) are published in order to get early feedback from the community, see these tracking issues for further discussions and enhancements.
The experimental modules are independent and backward-incompatible with stable ones.
Decoder.ts
moduleEncoder.ts
moduleCodec.ts
moduleEq.ts
moduleSchema.ts
module (advanced feature)
(*) A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice.
Top Related Projects
Runtime validation for static types
TypeScript-first schema validation with static type inference
A simple and composable way to validate data in JavaScript (and TypeScript).
Dead simple Object schema validation
Decorator-based property validation for classes.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot