Skip to main content Skills Marketplace Discover and explore AI skills built by the community.
Related occupations SOC
Based on SOC occupation classification
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill hono-validationThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... More from this repository LinkedIn automation via the Linked API CLI - fetch profiles, search people and companies, send messages, manage connections, create posts, react, comment, and run Sales Navigator and custom workflows. Use when the user wants to interact with LinkedIn.
Xquik X data automation API - Use REST or MCP for tweet search, user lookup, follower exports, media downloads, monitors, webhooks, giveaway draws, and confirmation-gated X actions.
MCP (Model Context Protocol) - Build AI-native servers with tools, resources, and prompts. TypeScript/Python SDKs for Claude Desktop integration.
name hono-validation description Hono request validation with Zod, TypeBox, Valibot - type-safe input validation for JSON, forms, query params, and headers user-invocable false disable-model-invocation true skill_version 1.0.0 updated_at "2025-01-03T00:00:00.000Z" tags ["hono","validation","zod","typebox","valibot","typescript","type-safety"] progressive_disclosure {"entry_point":{"summary":"Type-safe request validation with Zod, TypeBox, or Valibot integration","when_to_use":"Validating JSON bodies, form data, query parameters, headers, or path parameters","quick_start":"1. npm install @hono/zod-validator zod 2. Create schema 3. Apply zValidator middleware"},"references":[]} context_limit 800
Hono Validation Patterns
Overview
Hono provides a lightweight built-in validator and integrates seamlessly with popular validation libraries like Zod, TypeBox, and Valibot. Validation happens as middleware, providing type-safe access to validated data in handlers.
Key Features :
Built-in lightweight validator
First-class Zod integration via @hono/zod-validator
Standard Schema support (works with any validation library)
Type inference from validation schemas
Validates: JSON, forms, query params, headers, cookies, path params
When to Use This Skill
Use Hono validation when:
Validating API request bodies (JSON, form data)
Ensuring query parameters meet requirements
Validating authentication headers
Type-safe path parameter parsing
Cookie validation
Installation
npm install @hono/zod-validator zod
npm install @hono/typebox-validator @sinclair/typebox
npm install @hono/valibot-validator valibot
npm install @hono/standard-validator
Zod Validation (Recommended)
Basic Usage
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono ()
const createUserSchema = z.object ({
name : z.string ().min (1 ).max (100 ),
email : z. (). (),
: z. (). (). ( ). ( ). ()
})
app. (
,
( , createUserSchema),
{
data = c. . ( )
c. ({ : data }, )
}
)
string
email
age
number
int
min
0
max
150
optional
post
'/users'
zValidator
'json'
(c ) =>
const
req
valid
'json'
return
json
user
201
Validation Targets
app.post ('/api' , zValidator ('json' , schema), handler)
app.post ('/form' , zValidator ('form' , schema), handler)
app.get ('/search' , zValidator ('query' , z.object ({
q : z.string (),
page : z.coerce .number ().default (1 ),
limit : z.coerce .number ().max (100 ).default (20 )
})), handler)
app.get ('/users/:id' , zValidator ('param' , z.object ({
id : z.string ().uuid ()
})), handler)
app.post ('/api' , zValidator ('header' , z.object ({
'authorization' : z.string ().startsWith ('Bearer ' ),
'x-request-id' : z.string ().uuid ().optional ()
})), handler)
app.get ('/dashboard' , zValidator ('cookie' , z.object ({
session : z.string ().min (1 )
})), handler)
Custom Error Handling import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
app.post (
'/users' ,
zValidator ('json' , createUserSchema, (result, c ) => {
if (!result.success ) {
return c.json ({
error : 'Validation failed' ,
details : result.error .flatten ()
}, 400 )
}
}),
(c ) => {
const data = c.req .valid ('json' )
return c.json ({ user : data }, 201 )
}
)
Multiple Validators const paramsSchema = z.object ({
userId : z.string ().uuid ()
})
const bodySchema = z.object ({
name : z.string ().optional (),
email : z.string ().email ().optional ()
})
const querySchema = z.object ({
fields : z.string ().optional ()
})
app.patch (
'/users/:userId' ,
zValidator ('param' , paramsSchema),
zValidator ('json' , bodySchema),
zValidator ('query' , querySchema),
(c ) => {
const { userId } = c.req .valid ('param' )
const body = c.req .valid ('json' )
const { fields } = c.req .valid ('query' )
return c.json ({ updated : { userId, ...body } })
}
)
Common Zod Patterns
Coercion for Query/Form Data
const paginationSchema = z.object ({
page : z.coerce .number ().int ().min (1 ).default (1 ),
limit : z.coerce .number ().int ().min (1 ).max (100 ).default (20 ),
sort : z.enum (['asc' , 'desc' ]).default ('desc' )
})
app.get ('/items' , zValidator ('query' , paginationSchema), (c ) => {
const { page, limit, sort } = c.req .valid ('query' )
})
Optional with Defaults const configSchema = z.object ({
theme : z.enum (['light' , 'dark' ]).default ('light' ),
notifications : z.boolean ().default (true ),
language : z.string ().default ('en' )
})
Transformations const userSchema = z.object ({
email : z.string ().email ().toLowerCase (),
name : z.string ().trim (),
tags : z.string ().transform (s => s.split (',' )),
createdAt : z.string ().transform (s => new Date (s))
})
Refinements const passwordSchema = z.object ({
password : z.string ().min (8 ),
confirmPassword : z.string ()
}).refine (data => data.password === data.confirmPassword , {
message : "Passwords don't match" ,
path : ['confirmPassword' ]
})
const dateRangeSchema = z.object ({
startDate : z.coerce .date (),
endDate : z.coerce .date ()
}).refine (data => data.endDate > data.startDate , {
message : 'End date must be after start date'
})
Discriminated Unions const eventSchema = z.discriminatedUnion ('type' , [
z.object ({
type : z.literal ('click' ),
x : z.number (),
y : z.number ()
}),
z.object ({
type : z.literal ('scroll' ),
direction : z.enum (['up' , 'down' ])
}),
z.object ({
type : z.literal ('keypress' ),
key : z.string ()
})
])
app.post ('/events' , zValidator ('json' , eventSchema), (c ) => {
const event = c.req .valid ('json' )
if (event.type === 'click' ) {
console .log (event.x , event.y )
}
})
Built-in Validator For simple cases without external dependencies:
import { Hono } from 'hono'
import { validator } from 'hono/validator'
const app = new Hono ()
app.post (
'/posts' ,
validator ('json' , (value, c ) => {
const { title, body } = value
if (!title || typeof title !== 'string' ) {
return c.json ({ error : 'Title is required' }, 400 )
}
if (!body || typeof body !== 'string' ) {
return c.json ({ error : 'Body is required' }, 400 )
}
return { title, body }
}),
(c ) => {
const data = c.req .valid ('json' )
return c.json ({ post : data }, 201 )
}
)
TypeBox Validation import { tbValidator } from '@hono/typebox-validator'
import { Type } from '@sinclair/typebox'
const UserSchema = Type .Object ({
name : Type .String ({ minLength : 1 }),
email : Type .String ({ format : 'email' }),
age : Type .Optional (Type .Integer ({ minimum : 0 }))
})
app.post ('/users' , tbValidator ('json' , UserSchema ), (c ) => {
const user = c.req .valid ('json' )
return c.json ({ user }, 201 )
})
Valibot Validation import { vValidator } from '@hono/valibot-validator'
import * as v from 'valibot'
const UserSchema = v.object ({
name : v.string ([v.minLength (1 )]),
email : v.string ([v.email ()]),
age : v.optional (v.number ([v.integer (), v.minValue (0 )]))
})
app.post ('/users' , vValidator ('json' , UserSchema ), (c ) => {
const user = c.req .valid ('json' )
return c.json ({ user }, 201 )
})
Standard Schema Validator Works with any validation library implementing the Standard Schema spec:
import { standardValidator } from '@hono/standard-validator'
import { z } from 'zod'
app.post ('/users' , standardValidator ('json' , z.object ({
name : z.string (),
email : z.string ().email ()
})), handler)
File Upload Validation import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const uploadSchema = z.object ({
file : z.instanceof (File ).refine (
(file ) => file.size <= 5 * 1024 * 1024 ,
'File must be less than 5MB'
).refine (
(file ) => ['image/jpeg' , 'image/png' ].includes (file.type ),
'Only JPEG and PNG allowed'
),
description : z.string ().optional ()
})
app.post ('/upload' , zValidator ('form' , uploadSchema), async (c) => {
const { file, description } = c.req .valid ('form' )
const buffer = await file.arrayBuffer ()
return c.json ({ filename : file.name , size : file.size })
})
Reusable Schema Patterns
Create Schema Factory
import { z } from 'zod'
export const paginationSchema = z.object ({
page : z.coerce .number ().int ().min (1 ).default (1 ),
limit : z.coerce .number ().int ().min (1 ).max (100 ).default (20 )
})
export const idParamSchema = z.object ({
id : z.string ().uuid ()
})
export const timestampSchema = z.object ({
createdAt : z.string ().datetime (),
updatedAt : z.string ().datetime ()
})
app.get ('/items/:id' ,
zValidator ('param' , idParamSchema),
zValidator ('query' , paginationSchema),
handler
)
Extend Schemas const baseUserSchema = z.object ({
name : z.string ().min (1 ),
email : z.string ().email ()
})
const createUserSchema = baseUserSchema.extend ({
password : z.string ().min (8 )
})
const updateUserSchema = baseUserSchema.partial ()
const userResponseSchema = baseUserSchema.extend ({
id : z.string ().uuid (),
createdAt : z.string ().datetime ()
})
Best Practices
1. Validate Early
app.post ('/users' ,
zValidator ('json' , createUserSchema),
async (c) => {
const data = c.req .valid ('json' )
return c.json ({ user : data })
}
)
2. Use Appropriate Targets
zValidator ('json' , schema)
zValidator ('form' , schema)
zValidator ('query' , z.object ({ page : z.coerce .number () }))
zValidator ('param' , z.object ({ id : z.string () }))
3. Content-Type Matters
const schema = z.object ({ name : z.string () })
app.post ('/data' ,
async (c, next) => {
const contentType = c.req .header ('content-type' )
if (contentType?.includes ('application/json' )) {
return zValidator ('json' , schema)(c, next)
} else {
return zValidator ('form' , schema)(c, next)
}
},
handler
)
4. Lowercase Headers
zValidator ('header' , z.object ({
'authorization' : z.string (),
'x-custom-header' : z.string (),
}))
Error Response Format
Zod Flatten Format app.post ('/users' , zValidator ('json' , schema, (result, c ) => {
if (!result.success ) {
return c.json ({
success : false ,
error : result.error .flatten ()
}, 400 )
}
}), handler)
{
"success" : false ,
"error" : {
"formErrors" : [],
"fieldErrors" : {
"email" : ["Invalid email address" ],
"age" : ["Number must be greater than 0" ]
}
}
}
Zod Issues Format app.post ('/users' , zValidator ('json' , schema, (result, c ) => {
if (!result.success ) {
return c.json ({
success : false ,
errors : result.error .issues .map (issue => ({
field : issue.path .join ('.' ),
message : issue.message
}))
}, 400 )
}
}), handler)
{
"success" : false ,
"errors" : [
{ "field" : "email" , "message" : "Invalid email address" },
{ "field" : "age" , "message" : "Number must be greater than 0" }
]
}
Quick Reference
Zod Validator Targets Target Use Case Example jsonJSON body zValidator('json', schema)formForm data zValidator('form', schema)queryURL query params zValidator('query', schema)paramRoute params zValidator('param', schema)headerRequest headers zValidator('header', schema)cookieCookies zValidator('cookie', schema)
Common Zod Types z.string ()
z.number ()
z.boolean ()
z.date ()
z.enum (['a' , 'b' ])
z.array (z.string ())
z.object ({})
z.optional (z.string ())
z.nullable (z.string ())
z.coerce .number ()
z.string ().default ('val' )
Related Skills
hono-core - Framework fundamentals
hono-rpc - Type-safe RPC with validation
typescript-core - TypeScript patterns
Version : Hono 4.x, @hono/zod-validator 0.2.x
Last Updated : January 2025
License : MIT