Siddhant DevalAuthor
Senior Full-Stack Engineer·Aug 27, 2026·13 min read
Runtime Type Safety: Zod, Valibot & Parse-Don't-Validate
TypeScript types are erased at runtime. Any data crossing a trust boundary — API responses, localStorage, environment variables, user input — must be parsed, not cast. An `as ApiResponse` silences the compiler; it does not validate the data.
Technical Series
TypeScript Mastery
Part 9 of 11
Runtime Type Safety: Zod, Valibot & Parse-Don't-Validate
Types are a specification language — not an annotation layer. That means they are design-time tools. At runtime, TypeScript types are completely erased — they exist nowhere in the compiled JavaScript. When your application calls
fetch('/api/user') and casts the result as User, you have made a bet, not a guarantee. The compiler is silent. The only guarantee comes from parsing. This article is about building those guarantees correctly.1. The Trust Boundary Problem
Every application has trust boundaries — points where data enters from an untrusted source and must be validated before use. The most common ones:
| Source | Example | Why It's Untrusted |
|---|---|---|
Network (fetch) | GET /api/users → User[] | Server may change schema; API may return error shape |
localStorage | JSON.parse(localStorage.getItem('session')) | User may have modified stored data |
process.env | process.env.DATABASE_URL | May be missing or malformed at deploy time |
| URL parameters | new URLSearchParams(location.search).get('page') | User controls the URL |
JSON.parse() | Parsing uploaded files or webhooks | Shape is not guaranteed by the caller |
The anti-pattern at every boundary is a type cast:
typescript

Expand
2. Parse-Don't-Validate
The Parse-Don't-Validate principle (Alexis King, 2019) articulates the key insight: validation functions return a
boolean — they tell you if data is valid but hand back the same untyped value. Parse functions return a value of the target type — they encode the knowledge that validation passed into the return type itself.typescript
Zod and Valibot are implementations of this pattern — they provide composable schemas that act as parse functions.
3. Zod — The Standard Schema Library
3.1 Basic Schemas and Type Inference
typescript
3.2 .parse() vs .safeParse()
typescript

Expand
3.3 Schema Composition
typescript

Expand
4. Valibot — When Bundle Size Matters
Zod and Valibot have near-identical APIs. The meaningful difference is bundle size:
| Library | Min size | Gzip size | Architecture |
|---|---|---|---|
| Zod (v3) | ~57 KB | ~14 KB | Monolithic — full library in one import |
| Valibot | ~10 KB | ~3.6 KB | Modular — tree-shakeable; you pay only for what you use |
typescript
Pro Tip & Optimization
For client-side applications where bundle size is a concern (especially mobile web), prefer Valibot. For server-side Node.js applications or existing Zod-heavy codebases, Zod's larger ecosystem (React Hook Form resolver, tRPC, Drizzle) often outweighs the size difference.
5. Validating process.env at Startup
This is the highest-value, lowest-effort application of runtime parsing — it catches missing or malformed environment variables at startup, not when the affected code path first runs in production:
typescript
Summary
| Concept | Rule |
|---|---|
as T at runtime | Does nothing — type assertions are compile-time only; they are not runtime casts |
| Trust boundary | Every external data source (network, env, storage, URL) needs runtime parsing |
| Parse-don't-validate | Return the typed value, not a boolean — encode the validation result in the type |
.parse() | Throws ZodError on failure — use in server-side code where throws are acceptable |
.safeParse() | Returns a discriminated union — the correct choice at every UI/API boundary |
| Valibot vs. Zod | Valibot is ~4× smaller with equivalent API — prefer for client-side bundles |
process.env | Validate with a Zod schema at startup — catch missing vars before they cause runtime errors |
What's Next
In Part 10, we cover the ceiling of TypeScript mastery — Variance, Branded Types, and Exhaustiveness. These are the patterns that encode business rules into the type system so that illegal states are literally unrepresentable.
Research & Synthesis Note
This article was developed with AI-assisted deep search, specification cross-referencing, and technical research synthesis.
#TypeScript#Zod#Valibot#Runtime Safety#Schema Validation