{"id":11095,"library":"io-ts","title":"io-ts: Runtime Type System for TypeScript","description":"io-ts is a TypeScript library providing a robust runtime type system, designed for decoding and encoding data at the boundaries of your application. It allows developers to define types once using its codec combinators, which then serve for both static type checking during development and dynamic validation of external data at runtime. This approach significantly reduces common errors when integrating with uncertain data sources like API responses, user input, or configuration files. The current stable version is 2.2.22. The library maintains an active release cadence with frequent patch updates, often introducing and refining \"experimental\" features in dedicated modules while ensuring a stable core. A key differentiator is its deep integration with `fp-ts`, leveraging functional programming paradigms for highly composable type definitions and comprehensive error handling, promoting a type-safe and resilient approach to data processing.","status":"active","version":"2.2.22","language":"javascript","source_language":"en","source_url":"https://github.com/gcanti/io-ts","tags":["javascript","typescript","runtime","decoder","encoder","schema"],"install":[{"cmd":"npm install io-ts","lang":"bash","label":"npm"},{"cmd":"yarn add io-ts","lang":"bash","label":"yarn"},{"cmd":"pnpm add io-ts","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for functional programming utilities, error handling (Either), and pipe operator.","package":"fp-ts","optional":false}],"imports":[{"note":"Most `io-ts` codecs and combinators are exported as named exports, typically imported into a namespace `t` for brevity (e.g., `t.string`, `t.number`). CommonJS `require` is generally not idiomatic for modern TypeScript projects using `io-ts`.","wrong":"const t = require('io-ts');","symbol":"t","correct":"import * as t from 'io-ts';"},{"note":"The `PathReporter` utility, essential for human-readable error messages, is imported from a specific submodule, not the main `io-ts` entry point.","wrong":"import { PathReporter } from 'io-ts';","symbol":"PathReporter","correct":"import { PathReporter } from 'io-ts/PathReporter';"},{"note":"Since version 2.2+, `io-ts` introduced experimental modules like `io-ts/Decoder`. Features within these modules are highly experimental and are imported from their specific paths, often into their own namespaces (e.g., `D` for Decoder) to avoid clashes with stable `t` codecs.","wrong":"import * as D from 'io-ts';","symbol":"D","correct":"import * as D from 'io-ts/Decoder';"}],"quickstart":{"code":"import * as t from 'io-ts';\nimport { pipe } from 'fp-ts/function';\nimport * as E from 'fp-ts/Either';\nimport { PathReporter } from 'io-ts/PathReporter';\n\n// 1. Define a runtime type using io-ts codecs\nconst User = t.type({\n  id: t.number,\n  name: t.string,\n  email: t.string,\n  isAdmin: t.boolean,\n  tags: t.array(t.string),\n});\n\n// Infer the TypeScript type from the runtime type\ntype User = t.TypeOf<typeof User>;\n\n// 2. Data to decode\nconst validUserData = {\n  id: 123,\n  name: 'Alice',\n  email: 'alice@example.com',\n  isAdmin: false,\n  tags: ['developer', 'typescript'],\n};\n\nconst invalidUserData = {\n  id: 'abc', // Invalid type\n  name: 'Bob',\n  email: 'bob@example.com',\n  isAdmin: 'no', // Invalid type\n  tags: [123, 'tester'], // Mixed types\n};\n\n// 3. Decode valid data\npipe(\n  User.decode(validUserData),\n  E.fold(\n    (errors) => console.error('Failed to decode valid data:', PathReporter.report(E.left(errors))),\n    (user) => {\n      console.log('Successfully decoded valid user:', user);\n      const _user: User = user; // Type-check confirms 'user' is of type User\n      console.log('Is Alice an admin?', _user.isAdmin);\n    }\n  )\n);\n\n// 4. Decode invalid data and report errors\npipe(\n  User.decode(invalidUserData),\n  E.fold(\n    (errors) => console.error('Failed to decode invalid data:', PathReporter.report(E.left(errors))),\n    (user) => console.log('Unexpectedly decoded invalid user:', user)\n  )\n);\n\n// Example with a nullable/optional field\nconst OptionalUser = t.partial({\n  phone: t.string,\n});\n\nconst UserWithOptionalPhone = t.intersection([User, OptionalUser]);\n\nconst userWithPhone = {\n    id: 456,\n    name: 'Charlie',\n    email: 'charlie@example.com',\n    isAdmin: true,\n    tags: ['lead'],\n    phone: '555-1234'\n};\n\npipe(\n    UserWithOptionalPhone.decode(userWithPhone),\n    E.fold(\n        (errors) => console.log('Failed to decode user with phone:', PathReporter.report(E.left(errors))),\n        (user) => console.log('Decoded user with phone:', user)\n    )\n);\n","lang":"typescript","description":"This quickstart demonstrates how to define a runtime type for a `User` object, decode both valid and invalid data against that type, and leverage `fp-ts` and `PathReporter` for robust error handling and reporting. It also shows how to compose types with optional fields."},"warnings":[{"fix":"Update your `sum` definitions to use bracket notation for non-string tag values, for example: `D.sum('tag')({ [0]: t.type(...) })` instead of `D.sum('tag')({ 0: t.type(...) })`.","message":"The `sum` combinator underwent a breaking change in `io-ts@2.2.12`. For non-`string` tag values, the respective key in the sum object must now be enclosed in brackets (e.g., `D.sum('type')({ [1]: ... })`).","severity":"breaking","affected_versions":">=2.2.12"},{"fix":"Replace calls to `t.type` with `t.struct` and `t.fromType` with `t.fromStruct`.","message":"The `type` and `fromType` combinators were deprecated in `io-ts@2.2.15` in favor of `struct` and `fromStruct` respectively. While still functional, it's recommended to migrate to the newer alternatives.","severity":"deprecated","affected_versions":">=2.2.15"},{"fix":"Review the `io-ts` GitHub issues and documentation frequently if relying on experimental modules. Be prepared for potential refactoring during minor or patch updates that might affect these features.","message":"Experimental modules (e.g., `io-ts/Decoder`, `io-ts/Codec`, `io-ts/Encoder`) introduced in `io-ts@2.2+` are subject to change without notice and may be backward-incompatible with stable features. Use them with caution in production environments.","severity":"gotcha","affected_versions":">=2.2.0"},{"fix":"Ensure `fp-ts` is explicitly installed in your project: `npm install fp-ts`.","message":"`fp-ts` is a mandatory peer dependency for `io-ts`. Installation of `io-ts` alone will lead to runtime errors or TypeScript compilation issues due to missing functional programming utilities (e.g., `pipe`, `Either`).","severity":"gotcha","affected_versions":">=2.5.0"},{"fix":"Upgrade `io-ts` to at least `2.2.18` to ensure compatibility with `typescript@4.8` and newer versions.","message":"`io-ts` had specific bug fixes related to `typescript@4.8` errors in version `2.2.18`. Older versions might experience compilation issues with newer TypeScript releases.","severity":"gotcha","affected_versions":"<2.2.18"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using `import` statements (e.g., `import * as t from 'io-ts';`). Verify `tsconfig.json` has `\"module\": \"NodeNext\"` or `\"ESNext\"` and `\"moduleResolution\": \"NodeNext\"` or `\"Bundler\"`. For Node.js, ensure `\"type\": \"module\"` is set in your `package.json` if using ESM.","cause":"Attempting to use `require()` with an ESM-first module, incorrect `moduleResolution` in `tsconfig.json`, or an outdated Node.js environment/configuration.","error":"Error: Cannot find module 'io-ts' or its corresponding type declarations."},{"fix":"Install `fp-ts` as a dependency: `npm install fp-ts`. Also, ensure correct import paths like `import { pipe } from 'fp-ts/function';`.","cause":"The `fp-ts` library, which `io-ts` depends on for many functional utilities, is missing or incorrectly installed.","error":"TypeError: Cannot read properties of undefined (reading 'pipe') or TS2307: Cannot find module 'fp-ts/function'."},{"fix":"Examine the `PathReporter.report()` output for detailed error messages indicating exactly where the type mismatch occurred. Adjust the input data to match the expected `io-ts` codec schema.","cause":"The input data passed to an `io-ts` decoder does not conform to the defined schema. This specific error indicates `undefined` was provided where a `number` was expected at a particular path in the data structure.","error":"TypeError: Invalid value undefined supplied to /0: { type: number }"}],"ecosystem":"npm"}