[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AG04H0TWJR85R17K3DAXYK":3,"skill-same:01M6AG04H0TWJR85R17K3DAXYK":83},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":59,"commitSha":60,"skillDirectory":61,"forksCount":62,"repositoryHtmlUrl":63,"repositoryHomepageUrl":64,"ownerHtmlUrl":65,"ownerBlogUrl":66,"ownerDescription":67,"updatedAt":68,"install":69,"resources":82},"01M6AG04H0TWJR85R17K3DAXYK","hono",null,"Build ultra-fast web APIs and full-stack apps with Hono — runs on Cloudflare Workers, Deno, Bun, Node.js, and any WinterCG-compatible runtime.","davila7\u002Fclaude-code-templates","davila7","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6216945?v=4","01M6ADEWWFPS191NFM0Y1EX1JH","Daniel Avila","01M6ADJHGM78PHQRD3XZTFDVKK",33481,"MIT","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fweb-development\u002Fhono\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",[5,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],"deno","2026","ultra","apps","runtime","full","web-standards","cloudflare-workers","community","standards","cloudflare workers","safe","node","stack","api","edge","fast","cloudflare","web","gemini","typescript","2026-11-10 10:12:30",false,"---\nname: hono\ndescription: \"Build ultra-fast web APIs and full-stack apps with Hono — runs on Cloudflare Workers, Deno, Bun, Node.js, and any WinterCG-compatible runtime.\"\nmetadata:\n  category: backend\n  risk: safe\n  source: community\n  date_added: \"2026-03-18\"\n  author: suhaibjanjua\n  tags: [hono, edge, cloudflare-workers, bun, deno, api, typescript, web-standards]\n  tools: [claude, cursor, gemini]\n---\n\n# Hono Web Framework\n\n## Overview\n\nHono (炎, \"flame\" in Japanese) is a small, ultrafast web framework built on Web Standards (`Request`\u002F`Response`\u002F`fetch`). It runs anywhere: Cloudflare Workers, Deno Deploy, Bun, Node.js, AWS Lambda, and any WinterCG-compatible runtime — with the same code. Hono's router is one of the fastest available, and its middleware system, built-in JSX support, and RPC client make it a strong choice for edge APIs, BFFs, and lightweight full-stack apps.\n\n## When to Use This Skill\n\n- Use when building a REST or RPC API for edge deployment (Cloudflare Workers, Deno Deploy)\n- Use when you need a minimal but type-safe server framework for Bun or Node.js\n- Use when building a Backend for Frontend (BFF) layer with low latency requirements\n- Use when migrating from Express but wanting better TypeScript support and edge compatibility\n- Use when the user asks about Hono routing, middleware, `c.req`, `c.json`, or `hc()` RPC client\n\n## How It Works\n\n### Step 1: Project Setup\n\n**Cloudflare Workers (recommended for edge):**\n```bash\nnpm create hono@latest my-api\n# Select: cloudflare-workers\ncd my-api\nnpm install\nnpm run dev    # Wrangler local dev\nnpm run deploy # Deploy to Cloudflare\n```\n\n**Bun \u002F Node.js:**\n```bash\nmkdir my-api && cd my-api\nbun init\nbun add hono\n```\n\n```typescript\n\u002F\u002F src\u002Findex.ts (Bun)\nimport { Hono } from 'hono';\n\nconst app = new Hono();\n\napp.get('\u002F', c => c.text('Hello Hono!'));\n\nexport default {\n  port: 3000,\n  fetch: app.fetch,\n};\n```\n\n### Step 2: Routing\n\n```typescript\nimport { Hono } from 'hono';\n\nconst app = new Hono();\n\n\u002F\u002F Basic methods\napp.get('\u002Fposts', c => c.json({ posts: [] }));\napp.post('\u002Fposts', c => c.json({ created: true }, 201));\napp.put('\u002Fposts\u002F:id', c => c.json({ updated: true }));\napp.delete('\u002Fposts\u002F:id', c => c.json({ deleted: true }));\n\n\u002F\u002F Route params and query strings\napp.get('\u002Fposts\u002F:id', async c => {\n  const id = c.req.param('id');\n  const format = c.req.query('format') ?? 'json';\n  return c.json({ id, format });\n});\n\n\u002F\u002F Wildcard\napp.get('\u002Fstatic\u002F*', c => c.text('static file'));\n\nexport default app;\n```\n\n**Chained routing:**\n```typescript\napp\n  .get('\u002Fusers', listUsers)\n  .post('\u002Fusers', createUser)\n  .get('\u002Fusers\u002F:id', getUser)\n  .patch('\u002Fusers\u002F:id', updateUser)\n  .delete('\u002Fusers\u002F:id', deleteUser);\n```\n\n### Step 3: Middleware\n\nHono middleware works exactly like `fetch` interceptors — before and after handlers:\n\n```typescript\nimport { Hono } from 'hono';\nimport { logger } from 'hono\u002Flogger';\nimport { cors } from 'hono\u002Fcors';\nimport { bearerAuth } from 'hono\u002Fbearer-auth';\n\nconst app = new Hono();\n\n\u002F\u002F Built-in middleware\napp.use('*', logger());\napp.use('\u002Fapi\u002F*', cors({ origin: 'https:\u002F\u002Fmyapp.com' }));\napp.use('\u002Fapi\u002Fadmin\u002F*', bearerAuth({ token: process.env.API_TOKEN! }));\n\n\u002F\u002F Custom middleware\napp.use('*', async (c, next) => {\n  c.set('requestId', crypto.randomUUID());\n  await next();\n  c.header('X-Request-Id', c.get('requestId'));\n});\n```\n\n**Available built-in middleware:** `logger`, `cors`, `csrf`, `etag`, `cache`, `basicAuth`, `bearerAuth`, `jwt`, `compress`, `bodyLimit`, `timeout`, `prettyJSON`, `secureHeaders`.\n\n### Step 4: Request and Response Helpers\n\n```typescript\napp.post('\u002Fsubmit', async c => {\n  \u002F\u002F Parse body\n  const body = await c.req.json\u003C{ name: string; email: string }>();\n  const form = await c.req.formData();\n  const text = await c.req.text();\n\n  \u002F\u002F Headers and cookies\n  const auth = c.req.header('authorization');\n  const token = getCookie(c, 'session');\n\n  \u002F\u002F Responses\n  return c.json({ ok: true });                        \u002F\u002F JSON\n  return c.text('hello');                             \u002F\u002F plain text\n  return c.html('\u003Ch1>Hello\u003C\u002Fh1>');                    \u002F\u002F HTML\n  return c.redirect('\u002Fdashboard', 302);              \u002F\u002F redirect\n  return new Response(stream, { status: 200 });       \u002F\u002F raw Response\n});\n```\n\n### Step 5: Zod Validator Middleware\n\n```typescript\nimport { zValidator } from '@hono\u002Fzod-validator';\nimport { z } from 'zod';\n\nconst createPostSchema = z.object({\n  title: z.string().min(1).max(200),\n  body: z.string().min(1),\n  tags: z.array(z.string()).default([]),\n});\n\napp.post(\n  '\u002Fposts',\n  zValidator('json', createPostSchema),\n  async c => {\n    const data = c.req.valid('json'); \u002F\u002F fully typed\n    const post = await db.post.create({ data });\n    return c.json(post, 201);\n  }\n);\n```\n\n### Step 6: Route Groups and App Composition\n\n```typescript\n\u002F\u002F src\u002Froutes\u002Fposts.ts\nimport { Hono } from 'hono';\n\nconst posts = new Hono();\n\nposts.get('\u002F', async c => { \u002F* list posts *\u002F });\nposts.post('\u002F', async c => { \u002F* create post *\u002F });\nposts.get('\u002F:id', async c => { \u002F* get post *\u002F });\n\nexport default posts;\n```\n\n```typescript\n\u002F\u002F src\u002Findex.ts\nimport { Hono } from 'hono';\nimport posts from '.\u002Froutes\u002Fposts';\nimport users from '.\u002Froutes\u002Fusers';\n\nconst app = new Hono().basePath('\u002Fapi');\n\napp.route('\u002Fposts', posts);\napp.route('\u002Fusers', users);\n\nexport default app;\n```\n\n### Step 7: RPC Client (End-to-End Type Safety)\n\nHono's RPC mode exports route types that the `hc` client consumes — similar to tRPC but using fetch conventions:\n\n```typescript\n\u002F\u002F server: src\u002Froutes\u002Fposts.ts\nimport { Hono } from 'hono';\nimport { zValidator } from '@hono\u002Fzod-validator';\nimport { z } from 'zod';\n\nconst posts = new Hono()\n  .get('\u002F', c => c.json({ posts: [{ id: '1', title: 'Hello' }] }))\n  .post(\n    '\u002F',\n    zValidator('json', z.object({ title: z.string() })),\n    async c => {\n      const { title } = c.req.valid('json');\n      return c.json({ id: '2', title }, 201);\n    }\n  );\n\nexport default posts;\nexport type PostsType = typeof posts;\n```\n\n```typescript\n\u002F\u002F client: src\u002Fclient.ts\nimport { hc } from 'hono\u002Fclient';\nimport type { PostsType } from '..\u002Fserver\u002Froutes\u002Fposts';\n\nconst client = hc\u003CPostsType>('\u002Fapi\u002Fposts');\n\n\u002F\u002F Fully typed — autocomplete on routes, params, and responses\nconst { posts } = await client.$get().json();\nconst newPost = await client.$post({ json: { title: 'New Post' } }).json();\n```\n\n## Examples\n\n### Example 1: JWT Auth Middleware\n\n```typescript\nimport { Hono } from 'hono';\nimport { jwt, sign } from 'hono\u002Fjwt';\n\nconst app = new Hono();\nconst SECRET = process.env.JWT_SECRET!;\n\napp.post('\u002Flogin', async c => {\n  const { email, password } = await c.req.json();\n  const user = await validateUser(email, password);\n  if (!user) return c.json({ error: 'Invalid credentials' }, 401);\n\n  const token = await sign({ sub: user.id, exp: Math.floor(Date.now() \u002F 1000) + 3600 }, SECRET);\n  return c.json({ token });\n});\n\napp.use('\u002Fapi\u002F*', jwt({ secret: SECRET }));\napp.get('\u002Fapi\u002Fme', async c => {\n  const payload = c.get('jwtPayload');\n  const user = await getUserById(payload.sub);\n  return c.json(user);\n});\n\nexport default app;\n```\n\n### Example 2: Cloudflare Workers with D1 Database\n\n```typescript\n\u002F\u002F src\u002Findex.ts\nimport { Hono } from 'hono';\n\ntype Bindings = {\n  DB: D1Database;\n  API_TOKEN: string;\n};\n\nconst app = new Hono\u003C{ Bindings: Bindings }>();\n\napp.get('\u002Fusers', async c => {\n  const { results } = await c.env.DB.prepare('SELECT * FROM users LIMIT 50').all();\n  return c.json(results);\n});\n\napp.post('\u002Fusers', async c => {\n  const { name, email } = await c.req.json();\n  await c.env.DB.prepare('INSERT INTO users (name, email) VALUES (?, ?)')\n    .bind(name, email)\n    .run();\n  return c.json({ created: true }, 201);\n});\n\nexport default app;\n```\n\n### Example 3: Streaming Response\n\n```typescript\nimport { stream, streamText } from 'hono\u002Fstreaming';\n\napp.get('\u002Fstream', c =>\n  streamText(c, async stream => {\n    for (const chunk of ['Hello', ' ', 'World']) {\n      await stream.write(chunk);\n      await stream.sleep(100);\n    }\n  })\n);\n```\n\n## Best Practices\n\n- ✅ Use route groups (sub-apps) to keep handlers in separate files — `app.route('\u002Fusers', usersRouter)`\n- ✅ Use `zValidator` for all request body, query, and param validation\n- ✅ Type Cloudflare Workers bindings with the `Bindings` generic: `new Hono\u003C{ Bindings: Env }>()`\n- ✅ Use the RPC client (`hc`) when your frontend and backend share the same repo\n- ✅ Prefer returning `c.json()`\u002F`c.text()` over `new Response()` for cleaner code\n- ❌ Don't use Node.js-specific APIs (`fs`, `path`, `process`) if you want edge portability\n- ❌ Don't add heavy dependencies — Hono's value is its tiny footprint on edge runtimes\n- ❌ Don't skip middleware typing — use generics (`Variables`, `Bindings`) to keep `c.get()` type-safe\n\n## Security & Safety Notes\n\n- Always validate input with `zValidator` before using data from requests.\n- Use Hono's built-in `csrf` middleware on mutation endpoints when serving HTML\u002Fforms.\n- For Cloudflare Workers, store secrets in `wrangler.toml` `[vars]` (non-secret) or `wrangler secret put` (secret) — never hardcode them in source.\n- When using `bearerAuth` or `jwt`, ensure tokens are validated server-side — do not trust client-provided user IDs.\n- Rate-limit sensitive endpoints (auth, password reset) with Cloudflare Rate Limiting or a custom middleware.\n\n## Common Pitfalls\n\n- **Problem:** Handler returns `undefined` — response is empty\n  **Solution:** Always `return` a response from handlers: `return c.json(...)` not just `c.json(...)`.\n\n- **Problem:** Middleware runs after the response is sent\n  **Solution:** Call `await next()` before post-response logic; Hono runs code after `next()` as the response travels back up the chain.\n\n- **Problem:** `c.env` is undefined on Node.js\n  **Solution:** Cloudflare `env` bindings only exist in Workers. Use `process.env` on Node.js.\n\n- **Problem:** Route not matching — gets a 404\n  **Solution:** Check that `app.route('\u002Fprefix', subRouter)` uses the same prefix your client calls. Sub-routers should **not** repeat the prefix in their own routes.\n\n## Related Skills\n\n- `@cloudflare-workers-expert` — Deep dive into Cloudflare Workers platform specifics\n- `@trpc-fullstack` — Alternative RPC approach for TypeScript full-stack apps\n- `@zod-validation-expert` — Detailed Zod schema patterns used with `@hono\u002Fzod-validator`\n- `@nodejs-backend-patterns` — When you need a Node.js-specific backend (not edge)\n","# Hono Web Framework\n\n## Overview\n\nHono (炎, \"flame\" in Japanese) is a small, ultrafast web framework built on Web Standards (`Request`\u002F`Response`\u002F`fetch`). It runs anywhere: Cloudflare Workers, Deno Deploy, Bun, Node.js, AWS Lambda, and any WinterCG-compatible runtime — with the same code. Hono's router is one of the fastest available, and its middleware system, built-in JSX support, and RPC client make it a strong choice for edge APIs, BFFs, and lightweight full-stack apps.\n\n## When to Use This Skill\n\n- Use when building a REST or RPC API for edge deployment (Cloudflare Workers, Deno Deploy)\n- Use when you need a minimal but type-safe server framework for Bun or Node.js\n- Use when building a Backend for Frontend (BFF) layer with low latency requirements\n- Use when migrating from Express but wanting better TypeScript support and edge compatibility\n- Use when the user asks about Hono routing, middleware, `c.req`, `c.json`, or `hc()` RPC client\n\n## How It Works\n\n### Step 1: Project Setup\n\n**Cloudflare Workers (recommended for edge):**\n```bash\nnpm create hono@latest my-api\n# Select: cloudflare-workers\ncd my-api\nnpm install\nnpm run dev    # Wrangler local dev\nnpm run deploy # Deploy to Cloudflare\n```\n\n**Bun \u002F Node.js:**\n```bash\nmkdir my-api && cd my-api\nbun init\nbun add hono\n```\n\n```typescript\n\u002F\u002F src\u002Findex.ts (Bun)\nimport { Hono } from 'hono';\n\nconst app = new Hono();\n\napp.get('\u002F', c => c.text('Hello Hono!'));\n\nexport default {\n  port: 3000,\n  fetch: app.fetch,\n};\n```\n\n### Step 2: Routing\n\n```typescript\nimport { Hono } from 'hono';\n\nconst app = new Hono();\n\n\u002F\u002F Basic methods\napp.get('\u002Fposts', c => c.json({ posts: [] }));\napp.post('\u002Fposts', c => c.json({ created: true }, 201));\napp.put('\u002Fposts\u002F:id', c => c.json({ updated: true }));\napp.delete('\u002Fposts\u002F:id', c => c.json({ deleted: true }));\n\n\u002F\u002F Route params and query strings\napp.get('\u002Fposts\u002F:id', async c => {\n  const id = c.req.param('id');\n  const format = c.req.query('format') ?? 'json';\n  return c.json({ id, format });\n});\n\n\u002F\u002F Wildcard\napp.get('\u002Fstatic\u002F*', c => c.text('static file'));\n\nexport default app;\n```\n\n**Chained routing:**\n```typescript\napp\n  .get('\u002Fusers', listUsers)\n  .post('\u002Fusers', createUser)\n  .get('\u002Fusers\u002F:id', getUser)\n  .patch('\u002Fusers\u002F:id', updateUser)\n  .delete('\u002Fusers\u002F:id', deleteUser);\n```\n\n### Step 3: Middleware\n\nHono middleware works exactly like `fetch` interceptors — before and after handlers:\n\n```typescript\nimport { Hono } from 'hono';\nimport { logger } from 'hono\u002Flogger';\nimport { cors } from 'hono\u002Fcors';\nimport { bearerAuth } from 'hono\u002Fbearer-auth';\n\nconst app = new Hono();\n\n\u002F\u002F Built-in middleware\napp.use('*', logger());\napp.use('\u002Fapi\u002F*', cors({ origin: 'https:\u002F\u002Fmyapp.com' }));\napp.use('\u002Fapi\u002Fadmin\u002F*', bearerAuth({ token: process.env.API_TOKEN! }));\n\n\u002F\u002F Custom middleware\napp.use('*', async (c, next) => {\n  c.set('requestId', crypto.randomUUID());\n  await next();\n  c.header('X-Request-Id', c.get('requestId'));\n});\n```\n\n**Available built-in middleware:** `logger`, `cors`, `csrf`, `etag`, `cache`, `basicAuth`, `bearerAuth`, `jwt`, `compress`, `bodyLimit`, `timeout`, `prettyJSON`, `secureHeaders`.\n\n### Step 4: Request and Response Helpers\n\n```typescript\napp.post('\u002Fsubmit', async c => {\n  \u002F\u002F Parse body\n  const body = await c.req.json\u003C{ name: string; email: string }>();\n  const form = await c.req.formData();\n  const text = await c.req.text();\n\n  \u002F\u002F Headers and cookies\n  const auth = c.req.header('authorization');\n  const token = getCookie(c, 'session');\n\n  \u002F\u002F Responses\n  return c.json({ ok: true });                        \u002F\u002F JSON\n  return c.text('hello');                             \u002F\u002F plain text\n  return c.html('\u003Ch1>Hello\u003C\u002Fh1>');                    \u002F\u002F HTML\n  return c.redirect('\u002Fdashboard', 302);              \u002F\u002F redirect\n  return new Response(stream, { status: 200 });       \u002F\u002F raw Response\n});\n```\n\n### Step 5: Zod Validator Middleware\n\n```typescript\nimport { zValidator } from '@hono\u002Fzod-validator';\nimport { z } from 'zod';\n\nconst createPostSchema = z.object({\n  title: z.string().min(1).max(200),\n  body: z.string().min(1),\n  tags: z.array(z.string()).default([]),\n});\n\napp.post(\n  '\u002Fposts',\n  zValidator('json', createPostSchema),\n  async c => {\n    const data = c.req.valid('json'); \u002F\u002F fully typed\n    const post = await db.post.create({ data });\n    return c.json(post, 201);\n  }\n);\n```\n\n### Step 6: Route Groups and App Composition\n\n```typescript\n\u002F\u002F src\u002Froutes\u002Fposts.ts\nimport { Hono } from 'hono';\n\nconst posts = new Hono();\n\nposts.get('\u002F', async c => { \u002F* list posts *\u002F });\nposts.post('\u002F', async c => { \u002F* create post *\u002F });\nposts.get('\u002F:id', async c => { \u002F* get post *\u002F });\n\nexport default posts;\n```\n\n```typescript\n\u002F\u002F src\u002Findex.ts\nimport { Hono } from 'hono';\nimport posts from '.\u002Froutes\u002Fposts';\nimport users from '.\u002Froutes\u002Fusers';\n\nconst app = new Hono().basePath('\u002Fapi');\n\napp.route('\u002Fposts', posts);\napp.route('\u002Fusers', users);\n\nexport default app;\n```\n\n### Step 7: RPC Client (End-to-End Type Safety)\n\nHono's RPC mode exports route types that the `hc` client consumes — similar to tRPC but using fetch conventions:\n\n```typescript\n\u002F\u002F server: src\u002Froutes\u002Fposts.ts\nimport { Hono } from 'hono';\nimport { zValidator } from '@hono\u002Fzod-validator';\nimport { z } from 'zod';\n\nconst posts = new Hono()\n  .get('\u002F', c => c.json({ posts: [{ id: '1', title: 'Hello' }] }))\n  .post(\n    '\u002F',\n    zValidator('json', z.object({ title: z.string() })),\n    async c => {\n      const { title } = c.req.valid('json');\n      return c.json({ id: '2', title }, 201);\n    }\n  );\n\nexport default posts;\nexport type PostsType = typeof posts;\n```\n\n```typescript\n\u002F\u002F client: src\u002Fclient.ts\nimport { hc } from 'hono\u002Fclient';\nimport type { PostsType } from '..\u002Fserver\u002Froutes\u002Fposts';\n\nconst client = hc\u003CPostsType>('\u002Fapi\u002Fposts');\n\n\u002F\u002F Fully typed — autocomplete on routes, params, and responses\nconst { posts } = await client.$get().json();\nconst newPost = await client.$post({ json: { title: 'New Post' } }).json();\n```\n\n## Examples\n\n### Example 1: JWT Auth Middleware\n\n```typescript\nimport { Hono } from 'hono';\nimport { jwt, sign } from 'hono\u002Fjwt';\n\nconst app = new Hono();\nconst SECRET = process.env.JWT_SECRET!;\n\napp.post('\u002Flogin', async c => {\n  const { email, password } = await c.req.json();\n  const user = await validateUser(email, password);\n  if (!user) return c.json({ error: 'Invalid credentials' }, 401);\n\n  const token = await sign({ sub: user.id, exp: Math.floor(Date.now() \u002F 1000) + 3600 }, SECRET);\n  return c.json({ token });\n});\n\napp.use('\u002Fapi\u002F*', jwt({ secret: SECRET }));\napp.get('\u002Fapi\u002Fme', async c => {\n  const payload = c.get('jwtPayload');\n  const user = await getUserById(payload.sub);\n  return c.json(user);\n});\n\nexport default app;\n```\n\n### Example 2: Cloudflare Workers with D1 Database\n\n```typescript\n\u002F\u002F src\u002Findex.ts\nimport { Hono } from 'hono';\n\ntype Bindings = {\n  DB: D1Database;\n  API_TOKEN: string;\n};\n\nconst app = new Hono\u003C{ Bindings: Bindings }>();\n\napp.get('\u002Fusers', async c => {\n  const { results } = await c.env.DB.prepare('SELECT * FROM users LIMIT 50').all();\n  return c.json(results);\n});\n\napp.post('\u002Fusers', async c => {\n  const { name, email } = await c.req.json();\n  await c.env.DB.prepare('INSERT INTO users (name, email) VALUES (?, ?)')\n    .bind(name, email)\n    .run();\n  return c.json({ created: true }, 201);\n});\n\nexport default app;\n```\n\n### Example 3: Streaming Response\n\n```typescript\nimport { stream, streamText } from 'hono\u002Fstreaming';\n\napp.get('\u002Fstream', c =>\n  streamText(c, async stream => {\n    for (const chunk of ['Hello', ' ', 'World']) {\n      await stream.write(chunk);\n      await stream.sleep(100);\n    }\n  })\n);\n```\n\n## Best Practices\n\n- ✅ Use route groups (sub-apps) to keep handlers in separate files — `app.route('\u002Fusers', usersRouter)`\n- ✅ Use `zValidator` for all request body, query, and param validation\n- ✅ Type Cloudflare Workers bindings with the `Bindings` generic: `new Hono\u003C{ Bindings: Env }>()`\n- ✅ Use the RPC client (`hc`) when your frontend and backend share the same repo\n- ✅ Prefer returning `c.json()`\u002F`c.text()` over `new Response()` for cleaner code\n- ❌ Don't use Node.js-specific APIs (`fs`, `path`, `process`) if you want edge portability\n- ❌ Don't add heavy dependencies — Hono's value is its tiny footprint on edge runtimes\n- ❌ Don't skip middleware typing — use generics (`Variables`, `Bindings`) to keep `c.get()` type-safe\n\n## Security & Safety Notes\n\n- Always validate input with `zValidator` before using data from requests.\n- Use Hono's built-in `csrf` middleware on mutation endpoints when serving HTML\u002Fforms.\n- For Cloudflare Workers, store secrets in `wrangler.toml` `[vars]` (non-secret) or `wrangler secret put` (secret) — never hardcode them in source.\n- When using `bearerAuth` or `jwt`, ensure tokens are validated server-side — do not trust client-provided user IDs.\n- Rate-limit sensitive endpoints (auth, password reset) with Cloudflare Rate Limiting or a custom middleware.\n\n## Common Pitfalls\n\n- **Problem:** Handler returns `undefined` — response is empty\n  **Solution:** Always `return` a response from handlers: `return c.json(...)` not just `c.json(...)`.\n\n- **Problem:** Middleware runs after the response is sent\n  **Solution:** Call `await next()` before post-response logic; Hono runs code after `next()` as the response travels back up the chain.\n\n- **Problem:** `c.env` is undefined on Node.js\n  **Solution:** Cloudflare `env` bindings only exist in Workers. Use `process.env` on Node.js.\n\n- **Problem:** Route not matching — gets a 404\n  **Solution:** Check that `app.route('\u002Fprefix', subRouter)` uses the same prefix your client calls. Sub-routers should **not** repeat the prefix in their own routes.\n\n## Related Skills\n\n- `@cloudflare-workers-expert` — Deep dive into Cloudflare Workers platform specifics\n- `@trpc-fullstack` — Alternative RPC approach for TypeScript full-stack apps\n- `@zod-validation-expert` — Detailed Zod schema patterns used with `@hono\u002Fzod-validator`\n- `@nodejs-backend-patterns` — When you need a Node.js-specific backend (not edge)\n",{"name":5,"metadata":50,"description":7},{"risk":35,"tags":51,"tools":53,"author":56,"source":32,"category":57,"date_added":58},[5,39,31,52,24,38,44,30],"bun",[54,55,43],"claude","cursor","suhaibjanjua","backend","2026-03-18","main","2b749c82b5d11fac39d9a6e021ce3f5b8a541bd1","cli-tool\u002Fcomponents\u002Fskills\u002Fweb-development\u002Fhono",3931,"https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates","https:\u002F\u002Faitmpl.com","https:\u002F\u002Fgithub.com\u002Fdavila7","https:\u002F\u002Fdanielavila.me","Building AI dev tools with LLMs","2026-11-14 06:14:46",{"source":8,"skillName":5,"commands":70,"prompt":80,"zipAvailable":81},[71,74,77],{"tool":72,"command":73},"npx","npx skills add davila7\u002Fclaude-code-templates --skill hono",{"tool":75,"command":76},"bunx","bunx skills add davila7\u002Fclaude-code-templates --skill hono",{"tool":78,"command":79},"pnpm","pnpm dlx skills add davila7\u002Fclaude-code-templates --skill hono","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fweb-development\u002Fhono\u002FSKILL.md",true,[],[84,114,141,172,206,230],{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":93,"publishedAt":45},"01M70NHBTQ8BV0A2SCAZXEPHCX","wealthville-pool-scoring","Score DeFi liquidity pools before providing liquidity. Returns a 0-100 pool score and an Enter\u002FHold\u002FExit\u002FReduce\u002FAvoid verdict with calibrated confidence for ~68,800 Solana pools and 575 EVM pools, plus a public miss-inclusive track record. Use when asked whether a pool is worth LPing into, which pools look best right now, or how accurate the scores have actually been.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fweb-data\u002Fwealthville-pool-scoring\u002FSKILL.md",[90],{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113],"scoring","pool","wealthville pool scoring","liquidity","which","for","exit","now","use","when","reduce","with","record","track","verdict","evm","solana","how","public","look",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":121,"publishedAt":45},"01M70MB6VR8ERJ4EM8D5KHBMEV","technical-debt-auditor","Scans a codebase and produces a quantified technical debt report with a prioritized remediation plan. Analyzes dead code, TODO\u002FFIXME\u002FHACK markers, dependency staleness, complexity hotspots, code duplication signals, test coverage gaps, unused exports, and outdated patterns. Use this skill when the user asks to audit their codebase for tech debt, wants a health check of their code quality, says things like \"where should I focus refactoring\", \"find code smells\", \"audit my codebase\", \"what technical debt do we have\", \"prioritize cleanup work\", or asks about code quality metrics. Also trigger when the user mentions \"code rot\", \"legacy cleanup\", \"refactoring priorities\", or wants to understand the overall health of a project before a major effort. Trigger even if the user doesn't say \"technical debt\" explicitly — any request to systematically assess code quality and identify improvement priorities belongs here.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fdevelopment\u002Ftechnical-debt-auditor\u002FSKILL.md",[120],{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},[122,123,124,125,126,127,128,129,130,131,132,103,133,134,135,136,137,138,139,140],"technical debt","debt","technical","technical debt auditor","auditor","coverage","complexity","markers","project","cleanup","unused","code","todo","work","plan","focus","signals","audit","dependency",{"skillNo":142,"name":143,"nameZh":6,"description":144,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":145,"categories":146,"keywords":154,"publishedAt":45},"01M70KPYH9QNHCNME5GJQGE22K","readonly-sql-guard","Make an agent's database access provably read-only. Use when an agent runs caller-supplied SQL against a production\u002FERP\u002Fanalytics database (a \"query\" MCP tool, text-to-SQL, an admin console), or when reviewing DB-access code for write\u002FDDL\u002Fside-effect\u002Ftransaction-escape risks. Checks what a statement CALLS, not just its shape.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fdatabase\u002Freadonly-sql-guard\u002FSKILL.md",[147,148,149],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":150,"categoryName":151,"taxonomyType":152,"taxonomyTypeDesc":153},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[155,156,157,158,159,160,161,99,162,163,164,165,166,167,168,102,169,170,103,171],"readonly","guard","sql guard","sql","readonly sql guard","erp","effect","read-only","db","just","tool","calls","only","MCP","access","database","query",{"skillNo":173,"name":174,"nameZh":6,"description":175,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":176,"licenseFileUrl":177,"sourceHtmlUrl":178,"categories":179,"keywords":183,"publishedAt":45},"01M6AFY6F7CC2BBZP1QD6VTNVC","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FSKILL.md",[180],{"categoryNo":181,"categoryName":182,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[184,42,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,99,205],"artifacts builder","web artifacts builder","artifacts","builder","state","routing","state management","component","css","frontend","ui","Tools","file","components","shadcn","react","Tailwind","suite","jsx","html","single-file","ui components",{"skillNo":207,"name":208,"nameZh":6,"description":209,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":176,"licenseFileUrl":210,"sourceHtmlUrl":211,"categories":212,"keywords":217,"publishedAt":45},"01M6AFWF33SFV9Z3SF4PEEE4BF","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FSKILL.md",[213,216],{"categoryNo":214,"categoryName":215,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":181,"categoryName":182,"taxonomyType":21,"taxonomyTypeDesc":22},[218,219,220,221,222,42,223,193,194,224,225,226,227,99,228,105,229],"webapp testing","testing","webapp","browser","playwright","applications","debugging","toolkit","logs","screenshots","local","behavior",{"skillNo":231,"name":232,"nameZh":6,"description":233,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":176,"licenseFileUrl":234,"sourceHtmlUrl":235,"categories":236,"keywords":244,"publishedAt":45},"01M6AF67Q67JJJ5V51JR2P52KA","discernment-nudge","After you give a substantive answer or draft that the user may act on — advice or recommendations, drafted artifacts such as goals, plans, pitches, proposals, or emails, estimates or projections, analysis or interpretation of data, factual claims they may rely on, or a multi-step argument — invoke this skill BEFORE finalizing your reply and then, if it applies, append 2-3 short follow-up questions, each tied to something specific in what you just produced, that help the user check key facts, probe the reasoning or assumptions, and notice missing context. Do this at most once per conversation. Skip it when the user asked a trivial how-to or simple lookup, wants a purely educational explanation, asked you only to format, convert, or assemble a file from content they provided, is writing code they will run, is doing creative writing or casual chat, or already asked you to double-check, cite, or review — the skill file explains these boundaries and the exact output format.","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fdiscernment-nudge\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fdavila7\u002Fclaude-code-templates\u002Fblob\u002Fmain\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fdiscernment-nudge\u002FSKILL.md",[237,240,241],{"categoryNo":238,"categoryName":239,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":91,"categoryName":92,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":242,"categoryName":243,"taxonomyType":152,"taxonomyTypeDesc":153},"01JBSEEDCAT000000000000036","内容创作者",[245,246,247,248,249,250,251,252,186,253,196,133,254,255,256,257,258,167,259,103,260,261,262,263,264,111,265],"discernment nudge","nudge","interpretation","help","run","reasoning","data","writing","lookup","content","review","conversation","short","up","invoke","you","analysis","claims","argument","assemble","recommendations"]