Migrate Superstruct to Zod

Convert Superstruct’s bare-function API to Zod’s namespaced method chains. Gain access to Zod’s richer validation features, discriminated unions, branded types, and the largest TypeScript schema validation ecosystem.

Quick Start

Install SchemaShift globally and run the migration:

npm install -g schemashift-cli
schemashift migrate ./src -f superstruct -t zod
Pro+ Required

Superstruct → Zod migration requires a Pro or Team license. View pricing.

Before & After

Before (Superstruct)
import {
  object, string, number, integer, boolean,
  array, enums, optional, nullable, literal,
  union, type Infer
} from 'superstruct';

const UserSchema = object({
  name: string(),
  email: string(),
  age: optional(integer()),
  role: enums(['admin', 'user', 'guest']),
  tags: array(string()),
  bio: nullable(string()),
  active: boolean(),
  status: literal('active'),
  score: union([number(), literal('N/A')]),
});

type User = Infer<typeof UserSchema>;
After (Zod)
import { z } from 'zod';

const UserSchema = z.object({
  name: z.string(),
  email: z.string(),
  age: z.number().int().optional(),
  role: z.enum(['admin', 'user', 'guest']),
  tags: z.array(z.string()),
  bio: z.string().nullable(),
  active: z.boolean(),
  status: z.literal('active'),
  score: z.union([z.number(), z.literal('N/A')]),
});

type User = z.infer<typeof UserSchema>;

Conversion Reference

Superstruct Zod Notes
object({...}) z.object({...}) Bare function → namespaced method
string() z.string() Bare function → namespaced method
number() z.number() Bare function → namespaced method
boolean() z.boolean() Bare function → namespaced method
integer() z.number().int() Separate type in Superstruct; constraint in Zod
optional(schema) schema.optional() Wrapper function → chained method
nullable(schema) schema.nullable() Wrapper function → chained method
enums(['a', 'b']) z.enum(['a', 'b']) Direct mapping with name change
literal('val') z.literal('val') Direct mapping
union([a, b]) z.union([a, b]) Direct mapping
array(string()) z.array(z.string()) Nested bare functions → namespaced
record(string(), number()) z.record(z.string(), z.number()) Direct mapping
tuple([string(), number()]) z.tuple([z.string(), z.number()]) Direct mapping
Infer<typeof S> z.infer<typeof S> Type helper rewritten automatically

Edge Cases & Gotchas

Automated Migration

Run the full migration with dry-run first to preview changes:

# Preview changes without modifying files
schemashift migrate ./src -f superstruct -t zod --dry-run

# Run the actual migration
schemashift migrate ./src -f superstruct -t zod

# Export a diff for code review
schemashift migrate ./src -f superstruct -t zod --dry-run --output-diff changes.patch

# Verbose with HTML report
schemashift migrate ./src -f superstruct -t zod -v --report html

Post-Migration Checklist

Frequently Asked Questions

How do Superstruct bare functions map to Zod namespaced methods?

Superstruct uses bare function imports like string(), number(), object() while Zod uses namespaced methods like z.string(), z.number(), z.object(). SchemaShift automatically adds the z. namespace prefix to all schema constructors during migration. Import statements are rewritten from import { string, number } from 'superstruct' to import { z } from 'zod'.

How does Superstruct’s optional() wrapper convert to Zod?

Superstruct wraps schemas with optional(string()) while Zod chains .optional() as a method: z.string().optional(). SchemaShift automatically inverts the nesting, extracting the inner schema and appending .optional() as a chained method. The same applies to nullable().

Does Superstruct have an equivalent to Zod’s discriminatedUnion?

No. Superstruct does not have a discriminatedUnion equivalent. Superstruct’s union() checks each variant in order, while Zod’s discriminatedUnion() uses a discriminator key for efficient matching. When migrating union types, SchemaShift converts to z.union() by default. You can manually upgrade to z.discriminatedUnion() if your schemas have a common discriminator field.

Related Guides

Ready to migrate?

Convert your Superstruct schemas to Zod automatically with SchemaShift.

Get SchemaShift