Overview
The Guard module is heavily inspired by Zod; that’s not a coincidence, and it’s worth saying plainly. Zod’s chainable schema builders, type inference from schemas, and developer experience set a high bar for validation libraries in the TypeScript ecosystem. Guard borrows those core ideas directly. The differences are intentional design choices driven by how Guard fits into the broader ts-chas ecosystem, not attempts to replace Zod entirely. If your team already knows and loves Zod, that’s a great reason to keep using it. If you’re evaluating Guard, this page explains what’s the same and what’s different.What they share
Both Guard and Zod:- Define schemas with a chainable, declarative API
- Infer TypeScript types from schemas via utility types (
InferGuard/z.infer) - Implement Standard Schema v1 via the
~standardproperty, so both work with tRPC, react-hook-form, Drizzle, and any other Standard Schema-compatible library - Validate strings, numbers, booleans, objects, arrays, tuples, unions, intersections, enums, and literals
- Support custom validators and refinements
- Handle
null,undefined, and optional fields
Key differences
Guards as inline type predicates
Guards as inline type predicates
In Zod, you call This also works inline in type guard function signatures:You can use guards anywhere TypeScript expects a type predicate: in
.parse() or .safeParse() to validate a value. The schema and the type predicate are separate concerns.In ts-chas, every guard is the type predicate. You can call it directly as a function, and TypeScript narrows the type at the call site. You most likely don’t need a separate parse step for simple checks.if statements, Array.prototype.filter, assertion functions, or as standalone validators.Isomorphic hash validation — is.string.hash()
Isomorphic hash validation — is.string.hash()
ts-chas includes cryptographic hash validation via Zod has no built-in hash validation. You would need to implement this yourself using a separate library.
@noble/hashes, a well-audited, zero-dependency cryptography library. The implementation is isomorphic: it works identically in browser, Node.js, and edge runtimes like Cloudflare Workers and Deno, with no polyfills required.Result integration
Result integration
When you call Guard
.parse() on a guard in ts-chas, it returns a Result<T, GuardErr> , not a Zod-style { success, data, error } object. This means you can chain directly using the full Result API:.parse() is fail-fast: it returns on the first error. For collecting all errors across a nested structure, use defineSchemas (see below).Schema parsing returns typed error arrays
Schema parsing returns typed error arrays
When you define a schema with This is comparable to Zod’s
defineSchemas and call .parse(), you get Result<T, AggregateGuardError> : a class with an array of structured errors, one per failed field. Each error carries the field path, the expected type, and a human-readable message..safeParse() returning error.issues, but ts-chas returns the errors as a typed array in a Result, rather than inside a discriminated union object.Ecosystem integration
Ecosystem integration
Guards are designed to compose with the rest of ts-chas — This is unique to ts-chas.
Result, Task, and Option — without any adapter layer:Namespace extension
Namespace extension
You can extend the This is similar in spirit to Zod’s custom refinements, but
is namespace with your own guards while retaining full access to the built-in guards:is.extend creates a new is instance with a fully extended namespace, so you can share myIs across your codebase and call your custom guards exactly like built-in ones.When to use each
Use Zod if:- You’re in a Zod-centric codebase (tRPC v10 with Zod, Prisma Zod generators, etc.)
- Your team already knows Zod well and the switching cost isn’t worth the gain
- You need features Guard doesn’t yet have
- You want inline type predicate usage without a separate parse step
- You need isomorphic hash validation without a third-party dependency
- You want tight integration with
Result,Task, andOption - You’re building a new codebase and want a cohesive ecosystem
The Guard module is actively inspired by Zod’s excellent design. Many of the patterns you already know from Zod carry over directly. The two libraries are more complementary than competing: if you’re evaluating ts-chas/guard, you’ll find the mental model familiar, and the differences are additive rather than breaking.