Skip to content
Back to skills

Hono

ASecurity

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.

  • 57 stars
  • 0 votes
  • 0 copies
  • 8 views
  • Added May 31, 2026
developmenttypescriptnextjsnodeexpressgitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned May 31, 2026

npx -y skills add diegosouzapw/awesome-omni-skill --skill hono --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Hono?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Hono
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/diegosouzapw-hono/badge)](https://www.skillsdirectory.com/skills/diegosouzapw-hono)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: hono
description: "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."
proactive: match
match:
  - "hono"
  - "from 'hono'"
  - "c.json"
  - "c.text"
  - "c.env"
---

# Hono Web Framework Skill

> Lightweight, multi-runtime web framework. Key patterns that differ from Express.

## Quick Reference

### Minimal App
```typescript
import { Hono } from 'hono'

const app = new Hono()
app.get('/', (c) => c.text('Hello Hono!'))

export default app
```

### Key Differences from Express
| Express | Hono |
|---------|------|
| `req.params.id` | `c.req.param('id')` |
| `res.json(data)` | `return c.json(data)` |
| `next()` callback | `await next()` async |
| `process.env` | `c.env` (Workers) |

## Context Object (NOT req/res)

```typescript
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:**
```typescript
// ❌ Wrong - missing return
app.get('/', (c) => { c.json({ ok: true }) })

// ✅ Correct
app.get('/', (c) => { return c.json({ ok: true }) })
```

## Async Middleware

```typescript
// ❌ 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

```typescript
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)

```typescript
// 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

```typescript
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

```typescript
import { getRuntimeKey } from 'hono/adapter'
// 'workerd', 'bun', 'node', 'deno'
const runtime = getRuntimeKey()
```

## Cloudflare Workers

```typescript
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

```typescript
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 |
|----|-----|
| `c.jsonT()` | `c.json()` |
| `c.stream()` | `import { stream } from 'hono/streaming'` |
| `hono/nextjs` | `hono/vercel` |

## Anti-patterns

```typescript
// ❌ 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 }))
```

Reference: [Hono Docs](https://hono.dev), [GitHub](https://github.com/honojs/hono)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.