Awesome-omni-skill hono
Hono web framework patterns: Context-based API (not Express req/res), async middleware, Cloudflare/Bun/Node adapters, typed routes. Use when working with Hono projects.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/hono" ~/.claude/skills/diegosouzapw-awesome-omni-skill-hono && rm -rf "$T"
manifest:
skills/development/hono/SKILL.mdsource content
Hono Web Framework Skill
Lightweight, multi-runtime web framework. Key patterns that differ from Express.
Quick Reference
Minimal App
import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello Hono!')) export default app
Key Differences from Express
| Express | Hono |
|---|---|
| |
| |
callback | async |
| (Workers) |
Context Object (NOT req/res)
app.get('/users/:id', (c) => { const id = c.req.param('id') // NOT req.params.id const page = c.req.query('page') // NOT req.query.page const auth = c.req.header('Authorization') const body = await c.req.json() // JSON body // OR const form = await c.req.parseBody() // Form data return c.json({ id, page }) // MUST return })
Must return response:
// ❌ Wrong - missing return app.get('/', (c) => { c.json({ ok: true }) }) // ✅ Correct app.get('/', (c) => { return c.json({ ok: true }) })
Async Middleware
// ❌ Wrong - callback style app.use('*', (c, next) => { next() }) // ✅ Correct - async/await app.use('*', async (c, next) => { console.log('before') await next() console.log('after') })
Built-in Middleware
import { cors } from 'hono/cors' import { logger } from 'hono/logger' import { jwt } from 'hono/jwt' import { validator } from 'hono/validator' app.use('*', logger()) app.use('/api/*', cors()) // Validation app.post('/post', validator('json', (value, c) => { if (!value.title) return c.text('Invalid', 400) return value }))
RPC Client (hc)
// Server const route = app.get('/api', (c) => c.json({ ok: true })) export type AppType = typeof route // Client import { hc } from 'hono/client' const client = hc<AppType>('http://localhost:8787') const res = await client.api.$get()
JSX Engine
import { Hono } from 'hono' import { jsxRenderer } from 'hono/jsx-renderer' const app = new Hono() app.get('*', jsxRenderer(({ children }) => <html><body>{children}</body></html>)) app.get('/', (c) => c.render(<h1>Hello!</h1>))
Runtime Detection
import { getRuntimeKey } from 'hono/adapter' // 'workerd', 'bun', 'node', 'deno' const runtime = getRuntimeKey()
Cloudflare Workers
type Bindings = { MY_KV: KVNamespace API_KEY: string } const app = new Hono<{ Bindings: Bindings }>() app.get('/', (c) => { const key = c.env.API_KEY // NOT process.env return c.json({ key }) }) export default app
Node.js Setup
import { Hono } from 'hono' import { serve } from '@hono/node-server' const app = new Hono() app.get('/', (c) => c.text('Hello Node!')) serve({ fetch: app.fetch, port: 3000 })
v3 → v4 Migration
| v3 | v4 |
|---|---|
| |
| |
| |
Anti-patterns
// ❌ Don't use global env singleton export const env = (globalThis as any).env import { env } from './env' // Breaks request isolation // ✅ Always use c.env in handlers app.get('/', (c) => c.json({ key: c.env.API_KEY }))