Complete guide for building ultrafast web apps with Hono framework across Cloudflare Workers, Deno, Bun, Node.js, and other runtimes
Expert guide for building ultrafast web applications with Hono — the modern, lightweight web framework that runs on Cloudflare Workers, Deno, Bun, Node.js, and other JavaScript runtimes.
Hono is an ultrafast web framework designed for edge computing and serverless environments. It follows web standards, provides excellent developer experience, and works across multiple runtimes with the same codebase.
Use this skill when you need to:
**For new projects**, use the `create-hono` starter:
1. Run the appropriate command for your package manager:
- npm: `npm create hono@latest my-app`
- yarn: `yarn create hono my-app`
- pnpm: `pnpm create hono@latest my-app`
- bun: `bun create hono@latest my-app`
- deno: `deno init --npm hono@latest my-app`
2. Select your target platform when prompted (e.g., cloudflare-workers, deno, bun, nodejs, vercel, aws-lambda, etc.)
3. Navigate to the project directory and install dependencies:
- `cd my-app`
- Run `npm i`, `yarn`, `pnpm i`, or `bun i` depending on your package manager
4. Start the development server:
- `npm run dev`, `yarn dev`, `pnpm dev`, or `bun run dev`
**Create your Hono application** in `src/index.ts` (or `src/index.tsx` for JSX):
```typescript
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.text('Hello Hono!')
})
export default app
```
**Key points:**
**GET requests:**
```typescript
app.get('/', (c) => {
return c.text('Hello Hono!')
})
```
**POST, PUT, DELETE:**
```typescript
app.post('/posts', (c) => c.text('Created!', 201))
app.put('/posts/:id', (c) => c.text('Updated!'))
app.delete('/posts/:id', (c) =>
c.text(`${c.req.param('id')} is deleted!`)
)
```
**Path parameters:**
```typescript
app.get('/posts/:id', (c) => {
const id = c.req.param('id')
return c.text(`Post ID: ${id}`)
})
```
**Query parameters:**
```typescript
app.get('/search', (c) => {
const query = c.req.query('q')
const page = c.req.query('page')
return c.json({ query, page })
})
```
**Headers:**
```typescript
app.get('/posts/:id', (c) => {
c.header('X-Message', 'Hi!')
c.header('X-Custom-Header', 'Value')
return c.text('Response with custom headers')
})
```
**Text response:**
```typescript
app.get('/', (c) => c.text('Hello!'))
```
**JSON response:**
```typescript
app.get('/api/hello', (c) => {
return c.json({
ok: true,
message: 'Hello Hono!'
})
})
```
**HTML response (using html helper):**
```typescript
import { html } from 'hono/html'
app.get('/page', (c) => {
return c.html(html`
<html>
<body>
<h1>Hello Hono!</h1>
</body>
</html>
`)
})
```
**HTML with JSX (rename file to .tsx):**
```tsx
const View = () => {
return (
<html>
<body>
<h1>Hello Hono!</h1>
</body>
</html>
)
}
app.get('/page', (c) => {
return c.html(<View />)
})
```
**Raw Response:**
```typescript
app.get('/', () => {
return new Response('Good morning!')
})
```
**Apply middleware to routes:**
**Basic Authentication:**
```typescript
import { basicAuth } from 'hono/basic-auth'
app.use('/admin/*', basicAuth({
username: 'admin',
password: 'secret',
}))
app.get('/admin', (c) => {
return c.text('You are authorized!')
})
```
**Other built-in middleware options:**
**Example with multiple middleware:**
```typescript
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
app.use('*', logger())
app.use('/api/*', cors())
```
**For platform-specific features**, import from the appropriate adapter:
**Cloudflare Workers WebSocket:**
```typescript
import { upgradeWebSocket } from 'hono/cloudflare-workers'
app.get('/ws', upgradeWebSocket((c) => {
return {
onMessage: (event, ws) => {
ws.send('Hello from server!')
}
}
}))
```
**Other adapters available:**
1. **Local development:**
- Run `npm run dev` (or equivalent for your package manager)
- Access `http://localhost:8787` (default port may vary)
- Hot reload is typically enabled
2. **Code organization:**
- Keep main app in `src/index.ts` or `src/index.tsx`
- Split routes into separate files for larger apps
- Use TypeScript for type safety
3. **Testing:**
- Import routes and test with `app.request()`
- Use platform-specific testing tools
**API endpoint with error handling:**
```typescript
app.get('/api/user/:id', async (c) => {
try {
const id = c.req.param('id')
const user = await fetchUser(id)
if (!user) {
return c.json({ error: 'User not found' }, 404)
}
return c.json(user)
} catch (error) {
return c.json({ error: 'Internal server error' }, 500)
}
})
```
**Protected route with JWT:**
```typescript
import { jwt } from 'hono/jwt'
app.use('/api/protected/*', jwt({
secret: 'your-secret-key',
}))
app.get('/api/protected/data', (c) => {
const payload = c.get('jwtPayload')
return c.json({ data: 'secret', user: payload })
})
```
**Complete REST API example:**
```typescript
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
const app = new Hono()
app.use('*', logger())
app.use('/api/*', cors())
// Health check
app.get('/health', (c) => c.json({ status: 'ok' }))
// List resources
app.get('/api/posts', (c) => {
const page = c.req.query('page') || '1'
return c.json({ posts: [], page })
})
// Get single resource
app.get('/api/posts/:id', (c) => {
const id = c.req.param('id')
return c.json({ id, title: 'Sample Post' })
})
// Create resource
app.post('/api/posts', async (c) => {
const body = await c.req.json()
return c.json({ id: '123', ...body }, 201)
})
// Update resource
app.put('/api/posts/:id', async (c) => {
const id = c.req.param('id')
const body = await c.req.json()
return c.json({ id, ...body })
})
// Delete resource
app.delete('/api/posts/:id', (c) => {
const id = c.req.param('id')
return c.json({ message: `Post ${id} deleted` })
})
export default app
```
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/hono-web-framework-guide/raw