io-ts to Zod transformer for SchemaShift — converts io-ts codecs and types to Zod schemas
npm install @schemashift/io-ts-zodio-ts → Zod transformer for SchemaShift. Converts io-ts type definitions and codecs to Zod schemas with AST-based transformations.




Tier: Pro
``bash`
npm install @schemashift/io-ts-zod
`typescript
import { createIoTsToZodHandler } from '@schemashift/io-ts-zod';
import { TransformEngine } from '@schemashift/core';
const engine = new TransformEngine();
engine.registerHandler('io-ts', 'zod', createIoTsToZodHandler());
`
| io-ts | Zod |
|-------|-----|
| import * as t from 'io-ts' | import { z } from 'zod' |import t from 'io-ts'
| | import { z } from 'zod' |
io-ts primitives are accessed as properties without parentheses. They are converted to Zod function calls:
| io-ts | Zod |
|-------|-----|
| t.string | z.string() |t.number
| | z.number() |t.boolean
| | z.boolean() |t.null
| | z.null() |t.undefined
| | z.undefined() |t.void
| | z.void() |t.unknown
| | z.unknown() |t.any
| | z.any() |t.never
| | z.never() |t.Int
| | z.number().int() |t.Integer
| | z.number().int() |
| io-ts | Zod |
|-------|-----|
| t.type({...}) | z.object({...}) |t.partial({...})
| | z.object({...}).partial() |t.strict({...})
| | z.object({...}) |t.exact({...})
| | z.object({...}) |t.array(schema)
| | z.array(schema) |t.readonlyArray(schema)
| | z.array(schema) |t.record(key, value)
| | z.record(key, value) |t.tuple([a, b])
| | z.tuple([a, b]) |t.union([a, b])
| | z.union([a, b]) |t.intersection(a, b)
| | z.intersection(a, b) |t.literal(value)
| | z.literal(value) |t.keyof({...})
| | z.enum(Object.keys({...})) |t.refinement(schema, pred)
| | z.refine(schema, pred) |t.readonly(schema)
| | z.readonly(schema) |
| io-ts | Zod |
|-------|-----|
| t.TypeOf | z.infer |t.OutputOf
| | z.output |
io-ts uses fundamentally different patterns (Either monads, bidirectional codecs, fp-ts integration) that cannot be automatically converted 1:1. The transformer generates actionable warnings for these patterns.
`typescript
// io-ts
import { isRight } from 'fp-ts/Either';
const result = UserCodec.decode(data);
if (isRight(result)) {
const user = result.right;
}
// Zod (manual conversion)
const result = UserSchema.safeParse(data);
if (result.success) {
const user = result.data;
}
`
`typescript
// io-ts — bidirectional codec
const DateCodec = new t.Type
'Date',
(u): u is Date => u instanceof Date,
(u, c) => / decode /,
(date) => date.toISOString() // encode
);
// Zod — parse only, encoding is separate
// TODO(schemashift): Replace .decode()/.encode() with z.parse()/z.safeParse().
// Encoding must be handled separately.
`
`typescript
// io-ts
interface PositiveBrand { readonly Positive: unique symbol }
type Positive = t.Branded
// Zod (manual conversion)
const Positive = z.number().positive().brand<'Positive'>();
`
The transformer warns about fp-ts imports (Either, pipe, fold) that need conversion to standard try/catch or .safeParse()` patterns.
- schemashift-cli — CLI tool for running migrations
- @schemashift/core — Core analysis engine
- @schemashift/io-ts-effect — Alternative: io-ts → Effect Schema
MIT