**Status**: Production Ready ✅
Builds type-safe web APIs with Hono, Zod validation, and middleware patterns.
npx claudepluginhub secondsky/claude-skillsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/common-patterns.mdreferences/middleware-catalog.mdreferences/rpc-guide.mdreferences/setup-guide.mdreferences/top-errors.mdreferences/validation-libraries.mdscripts/check-versions.shtemplates/context-extension.tstemplates/error-handling.tstemplates/middleware-composition.tstemplates/package.jsontemplates/routing-patterns.tstemplates/rpc-client.tstemplates/rpc-pattern.tstemplates/validation-valibot.tstemplates/validation-zod.tsStatus: Production Ready ✅ Last Updated: 2025-11-21 Dependencies: None (framework-agnostic) Latest Versions: hono@4.10.6, zod@4.1.12, valibot@1.1.0
bun add hono@4.10.6 # preferred
# or: bun add hono@4.10.6
Why Hono:
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.json({ message: 'Hello Hono!' })
})
export default app
CRITICAL:
c.json(), c.text(), c.html() for responsesres.send() like Express)bun add zod@4.1.12 @hono/zod-validator@0.7.4
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const schema = z.object({
name: z.string(),
age: z.number(),
})
app.post('/user', zValidator('json', schema), (c) => {
const data = c.req.valid('json')
return c.json({ success: true, data })
})
✅ Return responses from handlers (c.json, c.text, c.html, etc.)
✅ Use c.req.valid('source') after validation middleware to get typed data
✅ Export app for deployment (Cloudflare Workers, Bun, Deno, Node.js)
✅ Use validation middleware (zValidator, vValidator) for type-safe request data
✅ Call await next() in middleware to pass control to next handler
✅ Use HTTPException for expected errors (returns proper HTTP status)
✅ Use template tag validators (zValidator, vValidator) not hooks
✅ Define context types for custom variables (Hono<{ Variables: { ... } }>)
✅ Use sub-apps (app.route()) for organizing large APIs
✅ Type your RPC routes (export type AppType = typeof routes) for client
❌ Never forget to return response from handlers
❌ Never use req.json() directly without validation - use c.req.valid()
❌ Never mix validation hooks with middleware - use middleware only
❌ Never forget await next() in middleware - breaks middleware chain
❌ Never use res.send() - not available (use c.json(), c.text(), etc.)
❌ Never skip error handling - use app.onError() for global handler
❌ Never access unvalidated data after validation middleware
❌ Never use blocking operations in middleware - breaks async chain
❌ Never hardcode origins in CORS - use environment variables
❌ Never skip type exports for RPC - client won't have types
Problem: Middleware returns response but route handler still executes Solution: Don't return from middleware if you want chain to continue - only set variables
// ❌ Wrong - breaks chain
app.use('*', (c) => {
return c.json({ error: 'Unauthorized' }, 401)
})
// ✅ Correct - throw HTTPException instead
app.use('*', (c, next) => {
if (!isAuthorized) {
throw new HTTPException(401, { message: 'Unauthorized' })
}
await next()
})
Problem: Using validation hooks instead of middleware Solution: Always use middleware validators (zValidator, vValidator)
// ❌ Wrong - hooks deprecated
app.post('/user', (c) => {
const data = c.req.json<User>() // No runtime validation!
})
// ✅ Correct - middleware with runtime validation
app.post('/user', zValidator('json', schema), (c) => {
const data = c.req.valid('json') // Validated & typed!
})
Problem: Middleware doesn't call next(), breaking chain Solution: Always call await next() unless returning early
// ❌ Wrong - chain broken
app.use('*', (c) => {
console.log('Log')
// Missing await next()!
})
// ✅ Correct
app.use('*', async (c, next) => {
console.log('Log')
await next()
})
Problem: c.get() and c.set() not typed Solution: Define Variables type in Hono constructor
// ❌ Wrong - no types
const app = new Hono()
c.set('user', { id: '123' }) // Not typed
const user = c.get('user') // any
// ✅ Correct - typed
type Variables = {
user: { id: string; name: string }
}
const app = new Hono<{ Variables: Variables }>()
c.set('user', { id: '123', name: 'Alice' })
const user = c.get('user') // Fully typed!
Problem: Client doesn't have types from server routes Solution: Export AppType and use hc<AppType>
// Server
const routes = app.get('/users', (c) => c.json([]))
export type AppType = typeof routes // Export this!
// Client
import { hc } from 'hono/client'
import type { AppType } from './server'
const client = hc<AppType>('http://localhost:8787') // Fully typed!
Load references/top-errors.md for all 12 errors with detailed solutions.
When: Simple CRUD operations Quick Pattern:
app.get('/users', (c) => c.json({ users: [] }))
app.post('/users', (c) => c.json({ created: true }))
app.get('/users/:id', (c) => c.json({ user: {} }))
app.put('/users/:id', (c) => c.json({ updated: true }))
app.delete('/users/:id', (c) => c.json({ deleted: true }))
Load: references/setup-guide.md → Complete Example
When: Need type-safe request validation Quick Pattern:
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
app.post('/user',
zValidator('json', z.object({
name: z.string(),
email: z.string().email(),
})),
(c) => {
const data = c.req.valid('json') // Typed!
return c.json(data)
}
)
Load: references/validation-libraries.md
When: Full-stack TypeScript with shared types
Load: references/rpc-guide.md + templates/rpc-pattern.ts
When: Authentication, logging, rate limiting
Load: references/middleware-catalog.md + templates/middleware-composition.ts
When: Share data between middleware and routes
Load: templates/context-extension.ts
Load references/setup-guide.md when:
Load references/top-errors.md when:
Load references/common-patterns.md when:
Load references/middleware-catalog.md when:
Load references/rpc-guide.md when:
Load references/validation-libraries.md when:
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.json({ message: 'Hello' }))
export default app
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
import { HTTPException } from 'hono/http-exception'
type Variables = {
user: { id: string; name: string }
requestId: string
}
const app = new Hono<{ Variables: Variables }>()
// Global middleware
app.use('*', logger())
app.use('*', async (c, next) => {
c.set('requestId', crypto.randomUUID())
await next()
})
app.use('*', cors({
origin: process.env.ALLOWED_ORIGINS?.split(',') || [],
credentials: true,
}))
// Routes
app.route('/api', apiRoutes)
// Global error handler
app.onError((err, c) => {
if (err instanceof HTTPException) {
return c.json(
{ error: err.message },
err.status
)
}
console.error(err)
return c.json(
{ error: 'Internal Server Error' },
500
)
})
// 404 handler
app.notFound((c) => {
return c.json({ error: 'Not Found' }, 404)
})
export default app
Required:
hono@^4.10.2 - Core frameworkChoose ONE validator (recommended):
zod@^4.1.12 + @hono/zod-validator@^0.7.4 (most popular)valibot@^1.1.0 + @hono/valibot-validator@^0.5.3 (smaller bundle)arktype@^2.0.0 + @hono/arktype-validator@^0.1.0 (fastest runtime)typia@^7.0.0 + @hono/typia-validator@^0.1.0 (compile-time validation)Optional:
@hono/node-server - Node.js adapter@cloudflare/workers-types - TypeScript types for Workers| Feature | Hono | Express | Fastify |
|---|---|---|---|
| Size | ~10KB | ~200KB | ~100KB |
| TypeScript | ✅ Native | ⚠️ Types | ✅ Native |
| Type Inference | ✅ Full | ❌ No | ⚠️ Limited |
| RPC | ✅ Built-in | ❌ No | ❌ No |
| Edge Runtime | ✅ Yes | ❌ No | ❌ No |
| Validation | ✅ Plugin | ⚠️ Manual | ✅ Plugin |
| Speed | Very Fast | Fast | Very Fast |
Recommendation:
Verified working projects:
bun add hono)Questions? Issues?
references/top-errors.md for all 12 errors and solutionsreferences/setup-guide.md for complete setup walkthroughreferences/common-patterns.md for production patternsreferences/middleware-catalog.md for built-in middlewarereferences/rpc-guide.md for type-safe client/serverExpert guidance for Next.js Cache Components and Partial Prerendering (PPR). **PROACTIVE ACTIVATION**: Use this skill automatically when working in Next.js projects that have `cacheComponents: true` in their next.config.ts/next.config.js. When this config is detected, proactively apply Cache Components patterns and best practices to all React Server Component implementations. **DETECTION**: At the start of a session in a Next.js project, check for `cacheComponents: true` in next.config. If enabled, this skill's patterns should guide all component authoring, data fetching, and caching decisions. **USE CASES**: Implementing 'use cache' directive, configuring cache lifetimes with cacheLife(), tagging cached data with cacheTag(), invalidating caches with updateTag()/revalidateTag(), optimizing static vs dynamic content boundaries, debugging cache issues, and reviewing Cache Component implementations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.