Superstruct vs Zod in 2026: Lightweight vs Feature-Rich Validation
TL;DR
Zod for most projects; Superstruct when bundle size is critical. Superstruct (~2M weekly downloads) is ~7KB gzipped and has a simple functional API. Zod (~20M downloads) is ~28KB but has richer built-in validators, better ecosystem integration, and more active development. For most web apps, Zod's size difference is negligible. For edge functions or browser bundles where every KB matters, Superstruct is worth evaluating.
Key Takeaways
- Zod: ~20M weekly downloads — Superstruct: ~2M (npm, March 2026)
- Superstruct: ~7KB gzipped — Zod: ~28KB gzipped
- Superstruct uses plain functions — no method chaining (different style)
- Zod has better TypeScript inference — Superstruct types require manual casting
- Zod is much more actively maintained — more contributors, faster releases
API Style
// Zod — method chains, OOP-ish API
import { z } from 'zod';
const User = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().positive(),
tags: z.array(z.string()).optional(),
});
const result = User.safeParse(data);
if (result.success) {
const user = result.data; // Typed as { name: string; email: string; ... }
}
// Superstruct — functional API, plain composable functions
import { object, string, number, array, optional, min, max, integer, positive } from 'superstruct';
const User = object({
name: string(), // min/max need to be added separately (custom types)
email: string(), // No built-in .email() — add custom refinement
age: integer(), // positive() refinement
tags: optional(array(string())),
});
const [error, value] = User.try(data);
// value is Infer<typeof User> = { name: string; email: string; ... }
Superstruct's functional style is composable but has fewer built-in validators. Zod's method chain style feels more natural to TypeScript developers.
Bundle Size
Library | Minified+Gzip | Note
--------------|---------------|------
Superstruct | ~7KB | Minimal, tree-shakeable
Valibot | ~8KB | Functional, tree-shakeable
ArkType | ~10KB | TypeScript-native syntax
Zod v4 | ~28KB | Full-featured
Joi | ~45KB | JavaScript-first, largest
For comparison: React is ~40KB gzipped
For a typical SaaS web app, the size difference between Superstruct and Zod is negligible (21KB in a >500KB bundle). It matters for:
- Edge functions with tight cold-start requirements
- Browser-only bundles on low-bandwidth targets
- Libraries that ship validation to users (don't want to impose large deps)
Custom Types
// Superstruct — custom types via refinement
import { refine, string } from 'superstruct';
const Email = refine(string(), 'Email', (value) => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
|| `Expected an email but got "${value}"`;
});
const PositiveNumber = refine(number(), 'PositiveNumber', (value) => {
return value > 0 || `Expected a positive number but got ${value}`;
});
// Zod — built-in types for common validations
z.string().email() // Built in
z.string().url() // Built in
z.string().uuid() // Built in
z.number().positive() // Built in
z.number().int() // Built in
// Custom refinement when needed:
z.string().refine(
(val) => isValidUsername(val),
{ message: 'Invalid username format' }
);
Transformation
// Superstruct — coerce utility
import { create, string, number } from 'superstruct';
const coerced = create('42', number()); // Throws if can't coerce
// Or use coerce() for default transformations:
import { coerce, defaulted } from 'superstruct';
const NumberFromString = coerce(number(), string(), (value) => parseFloat(value));
// Zod — transform built into schemas
const FormData = z.object({
age: z.string().transform(Number), // String → Number
date: z.string().transform(s => new Date(s)), // String → Date
name: z.string().trim().toLowerCase(), // Chain transforms
});
When to Choose
Choose Zod when:
- Standard web application development
- Using React Hook Form, tRPC, or Drizzle (native integrations)
- Bundle size isn't a constraint
- Richer built-in validators save time
- Team productivity over raw performance
Choose Superstruct when:
- Library author who doesn't want to impose large dependency on users
- Edge function bundle size is critical
- Functional composition style is preferred
- You need a lightweight validation baseline with custom extensions
The reality: for 95% of web development, Zod is the better choice. Superstruct's advantage is real but situational.
Compare Superstruct and Zod package health on PkgPulse.
See the live comparison
View superstruct vs. zod on PkgPulse →