Schemas & Standard Schema
Using Standard Schema compliant libraries like Zod, Valibot, and ArkType in Nooh.
Nooh adopts the Standard Schema specification (~standard). This means you are not locked into any single validation library — any schema library implementing Standard Schema works out of the box with zero glue code.
Supported Libraries
Zod
The standard in TypeScript schema validation with rich ecosystem support.
Valibot
Modular, tree-shakeable schema library with a tiny bundle footprint.
ArkType
Blazing fast, 1 TypeScript syntax string-based validator.
Defining Schemas
Here is how you define schemas using popular libraries:
import { z } from "zod";
export const CreateUserSchema = z.object({
name: z.string().min(2).max(50),
email: z.string().email(),
role: z.enum(["admin", "member"]).default("member"),
});
export type CreateUserInput = z.infer<typeof CreateUserSchema>;import * as v from "valibot";
export const CreateUserSchema = v.object({
name: v.pipe(v.string(), v.minLength(2), v.maxLength(50)),
email: v.pipe(v.string(), v.email()),
role: v.optional(v.picklist(["admin", "member"]), "member"),
});
export type CreateUserInput = v.InferOutput<typeof CreateUserSchema>;import { type } from "arktype";
export const CreateUserSchema = type({
name: "2 <= string <= 50",
email: "email",
"role?": "'admin' | 'member'",
});
export type CreateUserInput = typeof CreateUserSchema.infer;Standard Schema Contract
Under the hood, Nooh inspects the ~standard property on provided schema objects:
export interface NoohStandardSchema {
readonly "~standard": {
readonly validate: (value: never, ...args: never[]) => unknown;
readonly types?: {
readonly input?: unknown;
readonly output?: unknown;
};
};
}
This guarantees full compile-time type inference for your handler inputs (c.req.valid(...)) and outputs without runtime adapter overhead.