Skip to Content
guidesValidation

Last Updated: 3/7/2026


Validation

Hono provides only a very thin Validator. But, it can be powerful when combined with a third-party Validator. In addition, the RPC feature allows you to share API specifications with your clients through types.

Manual validator

First, introduce a way to validate incoming values without using the third-party Validator.

Import validator from hono/validator.

import { validator } from 'hono/validator'

To validate form data, specify form as the first argument and a callback as the second argument. In the callback, validates the value and return the validated values at the end. The validator can be used as middleware.

app.post( '/posts', validator('form', (value, c) => { const body = value['body'] if (!body || typeof body !== 'string') { return c.text('Invalid!', 400) } return { body: body, } }), //...

Within the handler you can get the validated value with c.req.valid('form').

, (c) => { const { body } = c.req.valid('form') // ... do something return c.json( { message: 'Created!', }, 201 ) }

Validation targets include json, query, header, param and cookie in addition to form.

WARNING: When you validate json or form, the request must contain a matching content-type header (e.g. Content-Type: application/json for json). Otherwise, the request body will not be parsed and you will receive an empty object ({}) as value in the callback.

WARNING: When you validate header, you need to use lowercase name as the key.

If you want to validate the Idempotency-Key header, you need to use idempotency-key as the key.

Multiple validators

You can also include multiple validators to validate different parts of request:

app.post( '/posts/:id', validator('param', ...), validator('query', ...), validator('json', ...), (c) => { //... }

With Zod

You can use Zod , one of third-party validators. We recommend using a third-party validator.

Install from the Npm registry.

npm i zod

Import z from zod.

import * as z from 'zod'

Write your schema.

const schema = z.object({ body: z.string(), })

You can use the schema in the callback function for validation and return the validated value.

const route = app.post( '/posts', validator('form', (value, c) => { const parsed = schema.safeParse(value) if (!parsed.success) { return c.text('Invalid!', 401) } return parsed.data }), (c) => { const { body } = c.req.valid('form') // ... do something return c.json( { message: 'Created!', }, 201 ) } )

Zod Validator Middleware

You can use the Zod Validator Middleware  to make it even easier.

npm i @hono/zod-validator

And import zValidator.

import { zValidator } from '@hono/zod-validator'

And write as follows.

const route = app.post( '/posts', zValidator( 'form', z.object({ body: z.string(), }) ), (c) => { const validated = c.req.valid('form') // ... use your validated data } )

Standard Schema Validator Middleware

Standard Schema  is a specification that provides a common interface for TypeScript validation libraries. It was created by the maintainers of Zod, Valibot, and ArkType to allow ecosystem tools to work with any validation library without needing custom adapters.

The Standard Schema Validator Middleware  lets you use any Standard Schema-compatible validation library with Hono, giving you the flexibility to choose your preferred validator while maintaining consistent type safety.

npm i @hono/standard-validator

Import sValidator from the package:

import { sValidator } from '@hono/standard-validator'

With Zod

You can use Zod with the Standard Schema validator:

import * as z from 'zod' import { sValidator } from '@hono/standard-validator' 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

Valibot  is a lightweight alternative to Zod with a modular design:

import * as v from 'valibot' import { sValidator } from '@hono/standard-validator' 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

ArkType  offers TypeScript-native syntax for runtime validation:

import { type } from 'arktype' import { sValidator } from '@hono/standard-validator' 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}`, }) })