Validation with Valibot
Valibot is a modular, tree-shakeable schema library that ships as a collection of small functions instead of a chained builder. It implements Standard Schema, so DaloyJS picks it up the same way it picks up Zod: no adapter, no wrapper, no extra runtime dependency in the framework.
Valibot is developed in the open at github.com/open-circle/valibot and published to npm as valibot: that's the package you install below.
Install
Why Valibot
- Bundle size. You import only the validators you actually use, which matters on edge runtimes and in browser-shipped contracts.
- Functional API.
v.pipe(v.string(), v.email())instead ofz.email(). Easier to compose, easier to lint. - Standard Schema native. Same handler types and the same problem+json error shape you get with Zod. DaloyJS does not care which one you picked.
What gets validated
For each route you can declare schemas for:
request.params: decoded path parameters. They start as strings, so usev.pipe(...)with transforms when you need stronger shapes.request.query: query string values. Repeated keys become arrays before validation.request.headers: request headers as lower-case names.request.body: parsed request bodies. The body is only read when declared.responses[status].body: typed and validated responses.
A complete route
body in the handler is inferred from CreateOrder. Returning anything that does not match Order is a TypeScript error, and DaloyJS also validates the response before serialization.
Params, query, and headers
Path params, query values, headers, and urlencoded form values arrive as strings before schema validation. Drop a v.transform or one of the built-in v.toNumber, v.toBoolean, or v.toDate actions into the pipe to convert before further validation.
- 01from the URLRaw string"?page=2"
- 02v.string()assert it is a string
- 03v.transform(Number)coerce to a number
- 04v.integer() · v.minValue(1)validate the result
- 05in your handlerTyped valuequery.page: number
Body limits and content types
When a route declares request.body, DaloyJS will also enforce:
- Content-Length and streamed size against
app.bodyLimitBytes→ 413. - Content-Type against the route's
acceptslist, or globalallowedContentTypesif set → 415. - Default accepted body types:
application/json,application/x-www-form-urlencoded, andmultipart/form-data. - Prototype-pollution-safe parsing for JSON, query strings, urlencoded forms, and multipart forms.
JSON bodies validate as parsed JSON. Urlencoded bodies validate as an object built from URLSearchParams. Multipart bodies validate as an object built from Request.formData(). For a custom text media type, opt in with accepts and validate a v.string() body.
Response validation
When a response schema is declared, DaloyJS validates the handler return before serializing it. Valibot object schemas return only declared keys by default, so the validated value also prevents undeclared fields from leaking to clients. Use v.looseObject() or v.objectWithRest() only when extra keys are part of the intended response contract.
Discriminated unions
Use v.variant for tagged unions. DaloyJS emits a proper discriminator in the OpenAPI document so generated clients get narrowing for free.
Reusing types
v.InferOutput mirrors Zod's z.infer. Use v.InferInput when you have transforms and need the pre-parse shape, for example in a form library.
Errors
Validation failures produce the same response as every other validator in DaloyJS: 422 Unprocessable Entity as RFC 9457 problem+json, with an errors array of per-issue path and messagerecords. You do not need to write an error handler. That is the framework's job.
OpenAPI
Valibot schemas are converted into JSON Schema by DaloyJS's OpenAPI generator the same way Zod schemas are. Run the CLI and your spec is in sync with the route definitions:
Mixing validators
Nothing stops you from using Valibot for one route and Zod for another in the same app. Both speak Standard Schema. That is useful when migrating a codebase incrementally, or when a shared package already exports its schemas in one library and you do not want to rewrite them.
See also
- Validation overview: how validators plug in via Standard Schema.
- Validation with Zod: the chainable alternative.
- OpenAPI generation: how schemas become a spec.
- Errors & problem+json: the error contract.