hono-api-scaffolder — Claude Code skill: install guide
Scaffolds Hono API routes for Cloudflare Workers with Zod validation, error handling and API docs. Use it after the project shell is in place.
npx skills add jezweb/claude-skills --skill hono-api-scaffolder -a claude-codeWhat hono-api-scaffolder does
This skill groups API endpoints by resource, creates route files, and mounts them from the main entry point. It adds typed environment bindings, request validation with @hono/zod-validator and zod, plus an error handler that returns JSON.
It includes templates for authorization middleware and Hono CORS middleware. The skill also writes API_ENDPOINTS.md, documenting endpoint methods, auth requirements, request bodies, and responses.
Use it in a Cloudflare Workers project created with cloudflare-worker-builder or vite-flare-starter. It is compatible with Claude Code only, so that limitation matters before adding it to another coding agent.
What it helps with
- create API routes for resource groups
- validate request bodies with Zod
- return JSON errors from API handlers
- document endpoints in
API_ENDPOINTS.md - define
Envbindings for D1, KV, and R2
Example prompts for the agent
- Add Hono routes for users and mount them in
src/index.ts. - Create
POST /api/userswith a Zod request body schema. - Generate
API_ENDPOINTS.mdfor the current API routes.
How to install hono-api-scaffolder
1Skills CLI (Vercel)
npx skills add jezweb/claude-skills --skill hono-api-scaffolder -a claude-code2Manually: put the files in place
~/.claude/skills/hono-api-scaffolder/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/hono-api-scaffolder/
1Skills CLI (Vercel)
npx skills add jezweb/claude-skills --skill hono-api-scaffolder -a codex2Manually: put the files in place
.agents/skills/hono-api-scaffolder/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add jezweb/claude-skills --skill hono-api-scaffolder -a cursor2Manually: put the files in place
.cursor/skills/hono-api-scaffolder/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install jezweb/claude-skills hono-api-scaffolder2Manually: put the files in place
.github/skills/hono-api-scaffolder/SKILL.md1Skills CLI (Vercel)
npx skills add jezweb/claude-skills --skill hono-api-scaffolder -a gemini-cli2Platform CLI
gemini skills install https://github.com/jezweb/claude-skills --path archive/plugins/cloudflare/skills/hono-api-scaffolderManually: put the files in place
.devin/skills/hono-api-scaffolder/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add jezweb/claude-skills --skill hono-api-scaffolder -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about hono-api-scaffolder
How do I install hono-api-scaffolder in Claude Code?
Run npx skills add jezweb/claude-skills --skill hono-api-scaffolder -a claude-code, then run npx skills add jezweb/claude-skills --skill hono-api-scaffolder -a claude-code again and open ~/.claude/skills/hono-api-scaffolder/SKILL.md.
What does hono-api-scaffolder do?
It scaffolds Hono routes for Cloudflare Workers, including resource files, middleware, environment types, Zod validation, and API_ENDPOINTS.md. It also mounts route groups in the application entry point.
What is required for Zod request validation?
Request validation uses @hono/zod-validator and zod. Install them with pnpm add @hono/zod-validator zod.
Source text
SKILL.md · MIT
---
name: hono-api-scaffolder
description: "Scaffold Hono API routes for Cloudflare Workers. Produces route files, middleware, typed bindings, Zod validation, error handling, and API_ENDPOINTS.md documentation. Use after a project is set up with cloudflare-worker-builder or vite-flare-starter, when you need to add API routes, create endpoints, or generate API documentation."
compatibility: claude-code-only
---
# Hono API Scaffolder
Add structured API routes to an existing Cloudflare Workers project. This skill runs AFTER the project shell exists (via cloudflare-worker-builder or vite-flare-starter) and produces route files, middleware, and endpoint documentation.
## Workflow
### Step 1: Gather Endpoints
Determine what the API needs. Either ask the user or infer from the project description. Group endpoints by resource:
```
Users: GET /api/users, GET /api/users/:id, POST /api/users, PUT /api/users/:id, DELETE /api/users/:id
Posts: GET /api/posts, GET /api/posts/:id, POST /api/posts, PUT /api/posts/:id
Auth: POST /api/auth/login, POST /api/auth/logout, GET /api/auth/me
```
### Step 2: Create Route Files
One file per resource group. Use the template from [assets/route-template.ts](assets/route-template.ts):
```typescript
// src/routes/users.ts
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
import type { Env } from '../types'
const app = new Hono<{ Bindings: Env }>()
// GET /api/users
app.get('/', async (c) => {
const db = c.env.DB
const { results } = await db.prepare('SELECT * FROM users').all()
return c.json({ users: results })
})
// GET /api/users/:id
app.get('/:id', async (c) => {
const id = c.req.param('id')
const user = await db.prepare('SELECT * FROM users WHERE id = ?').bind(id).first()
if (!user) return c.json({ error: 'Not found' }, 404)
return c.json({ user })
})
// POST /api/users
const createUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
})
app.post('/', zValidator('json', createUserSchema), async (c) => {
const body = c.req.valid('json')
// ... insert logic
return c.json({ user }, 201)
})
export default app
```
### Step 3: Add Middleware
Based on project needs, add from [assets/middleware-template.ts](assets/middleware-template.ts):
**Auth middleware** — protect routes requiring authentication:
```typescript
import { createMiddleware } from 'hono/factory'
import type { Env } from '../types'
export const requireAuth = createMiddleware<{ Bindings: Env }>(async (c, next) => {
const token = c.req.header('Authorization')?.replace('Bearer ', '')
if (!token) return c.json({ error: 'Unauthorized' }, 401)
// Validate token...
await next()
})
```
**CORS** — use Hono's built-in:
```typescript
import { cors } from 'hono/cors'
app.use('/api/*', cors({ origin: ['https://example.com'] }))
```
### Step 4: Wire Routes
Mount all route groups in the main entry point:
```typescript
// src/index.ts
import { Hono } from 'hono'
import type { Env } from './types'
import users from './routes/users'
import posts from './routes/posts'
import auth from './routes/auth'
import { errorHandler } from './middleware/error-handler'
const app = new Hono<{ Bindings: Env }>()
// Global error handler
app.onError(errorHandler)
// Mount routes
app.route('/api/users', users)
app.route('/api/posts', posts)
app.route('/api/auth', auth)
// Health check
app.get('/api/health', (c) => c.json({ status: 'ok' }))
export default app
```
### Step 5: Create Types
```typescript
// src/types.ts
export interface Env {
DB: D1Database
KV: KVNamespace // if needed
R2: R2Bucket // if needed
API_SECRET: string // secrets
}
```
### Step 6: Generate API_ENDPOINTS.md
Document all endpoints. See [references/endpoint-docs-template.md](references/endpoint-docs-template.md) for the format:
```markdown
## POST /api/users
Create a new user.
- **Auth**: Required (Bearer token)
- **Body**: `{ name: string, email: string }`
- **Response 201**: `{ user: User }`
- **Response 400**: `{ error: string, details: ZodError }`
```
## Key Patterns
### Zod Validation
Always validate request bodies with `@hono/zod-validator`:
```typescript
import { zValidator } from '@hono/zod-validator'
app.post('/', zValidator('json', schema), async (c) => {
const body = c.req.valid('json') // fully typed
})
```
Install: `pnpm add @hono/zod-validator zod`
### Error Handling
Use the standard error handler from [assets/error-handler.ts](assets/error-handler.ts):
```typescript
export const errorHandler = (err: Error, c: Context) => {
console.error(err)
return c.json({ error: err.message }, 500)
}
```
**API routes must return JSON errors, not redirects.** `fetch()` follows redirects silently, then the client tries to parse HTML as JSON.
### RPC Type Safety
For end-to-end type safety between Worker and client:
```typescript
// Worker: export the app type
export type AppType = typeof app
// Client: use hc (Hono Client)
import { hc } from 'hono/client'
import type { AppType } from '../worker/src/index'
const client = hc<AppType>('https://api.example.com')
const res = await client.api.users.$get() // fully typed
```
### Route Groups vs Single File
| Project size | Structure |
|-------------|-----------|
| < 10 endpoints | Single `index.ts` with all routes |
| 10-30 endpoints | Route files per resource (`routes/users.ts`) |
| 30+ endpoints | Route files + shared middleware + typed context |
## Reference Files
| When | Read |
|------|------|
| Hono patterns, middleware, RPC | [references/hono-patterns.md](references/hono-patterns.md) |
| API_ENDPOINTS.md format | [references/endpoint-docs-template.md](references/endpoint-docs-template.md) |
## Assets
| File | Purpose |
|------|---------|
| [assets/route-template.ts](assets/route-template.ts) | Starter route file with CRUD + Zod |
| [assets/middleware-template.ts](assets/middleware-template.ts) | Auth middleware template |
| [assets/error-handler.ts](assets/error-handler.ts) | Standard JSON error handler |
© jezweb · MIT · jezweb/claude-skills