Skip to Content
guidesValidation

Last Updated: 3/11/2026


Validation

Hono provides a lightweight validator that becomes powerful when combined with third-party validation libraries like Zod, Valibot, or ArkType.

Manual Validation

Use the validator function for basic validation:

import { validator } from 'hono/validator' app.post( '/posts', validator('form', (value, c) => { const body = value['body'] if (!body || typeof body !== 'string') { return c.text('Invalid!', 400) } return { body } }), (c) => { const { body } = c.req.valid('form') return c.json({ message: 'Created!', body }, 201) } )

Validation Targets

Validate different parts of the request:

  • json - Request body (JSON)
  • form - Form data
  • query - URL query parameters
  • param - Path parameters
  • header - Request headers
  • cookie - Cookies

Important: For json and form, the request must have the matching Content-Type header.

Zod Validator

Use Zod for schema validation:

npm install @hono/zod-validator zod
import { zValidator } from '@hono/zod-validator' import { z } from 'zod' const schema = z.object({ title: z.string().min(1), body: z.string().min(10), }) app.post( '/posts', zValidator('json', schema), (c) => { const { title, body } = c.req.valid('json') return c.json({ message: 'Created!', title, body }, 201) } )

Standard Schema Validator

The Standard Schema validator works with multiple validation libraries:

npm install @hono/standard-validator

With Zod

import { sValidator } from '@hono/standard-validator' import * as z from 'zod' const schema = z.object({ name: z.string(), age: z.number(), }) app.post('/author', sValidator('json', schema), (c) => { const data = c.req.valid('json') return c.json({ success: true, message: `${data.name} is ${data.age}`, }) })

With Valibot

npm install valibot
import { sValidator } from '@hono/standard-validator' import * as v from 'valibot' const schema = v.object({ name: v.string(), age: v.number(), }) app.post('/author', sValidator('json', schema), (c) => { const data = c.req.valid('json') return c.json({ success: true, message: `${data.name} is ${data.age}` }) })

With ArkType

npm install arktype
import { sValidator } from '@hono/standard-validator' import { type } from 'arktype' const schema = type({ name: 'string', age: 'number', }) app.post('/author', sValidator('json', schema), (c) => { const data = c.req.valid('json') return c.json({ success: true, message: `${data.name} is ${data.age}` }) })

Multiple Validators

Validate different parts of a request:

app.post( '/posts/:id', zValidator('param', z.object({ id: z.string() })), zValidator('query', z.object({ page: z.string().optional() })), zValidator('json', z.object({ title: z.string(), body: z.string() })), (c) => { const { id } = c.req.valid('param') const { page } = c.req.valid('query') const { title, body } = c.req.valid('json') return c.json({ id, page, title, body }) } )

Header Validation

When validating headers, use lowercase keys:

app.post( '/api', validator('header', (value, c) => { // Use lowercase 'idempotency-key' const idempotencyKey = value['idempotency-key'] if (!idempotencyKey) { return c.json({ error: 'Idempotency-Key required' }, 400) } return { idempotencyKey } }), (c) => { const { idempotencyKey } = c.req.valid('header') return c.json({ received: idempotencyKey }) } )

Error Handling

Handle validation errors:

import { zValidator } from '@hono/zod-validator' import { z } from 'zod' app.post( '/posts', zValidator( 'json', z.object({ title: z.string(), }), (result, c) => { if (!result.success) { return c.json({ error: result.error.errors }, 400) } } ), (c) => { const data = c.req.valid('json') return c.json({ success: true, data }) } )

Next Steps

Learn about type-safe client-server communication with RPC.