Bun Hono Integration

作者 secondsky88378361314fMIT227 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫10 天前更新

Use when building APIs with Hono framework on Bun, including routing, middleware, REST APIs, context handling, or web framework features.

AI 產生的概覽

在 Bun 執行環境上以 Hono 建構 Web API 的參考指南,涵蓋路由、中介軟體、驗證、情境與錯誤處理。

功能
此技能提供在 Bun 上使用 Hono 框架建構 Web API 的說明與程式碼範例。內容涵蓋專案初始化、路由與路由分組、請求與回應處理、中介軟體(包含內建的 CORS、記錄器、驗證、壓縮與安全標頭)、Zod 驗證、具型別的情境變數、錯誤處理,以及型別安全的 RPC 用戶端。它也指向選用的參考檔案,用於完整中介軟體清單與 OpenAPI 整合。
適用情境
適用於在 Bun 上以 Hono 撰寫或組織 API 的情境,例如定義路由、加入中介軟體、驗證請求資料,或建立型別安全的用戶端。也適合排查 Hono 常見錯誤,例如路由不符、重複讀取請求主體或中介軟體順序問題。
執行需求
需要 Bun 執行環境與 Hono 套件,驗證範例另需 @hono/zod-validator 與 zod。此技能未附帶指令碼,僅包含說明與程式碼範例。

Bun Hono Integration

Hono is a fast, lightweight web framework optimized for Bun.

Quick Start

bash
bun create hono my-appcd my-appbun installbun run dev

Basic Setup

typescript
import { Hono } from "hono";
const app = new Hono();
app.get("/", (c) => c.text("Hello Hono!"));
app.get("/json", (c) => c.json({ message: "Hello" }));
export default app;

Routing

typescript
import { Hono } from "hono";
const app = new Hono();
// HTTP methodsapp.get("/users", (c) => c.json([]));app.post("/users", (c) => c.json({ created: true }));app.put("/users/:id", (c) => c.json({ updated: true }));app.delete("/users/:id", (c) => c.json({ deleted: true }));
// All methodsapp.all("/any", (c) => c.text("Any method"));
// Path parametersapp.get("/users/:id", (c) => {  const id = c.req.param("id");  return c.json({ id });});
// Multiple parametersapp.get("/posts/:postId/comments/:commentId", (c) => {  const { postId, commentId } = c.req.param();  return c.json({ postId, commentId });});
// Wildcardsapp.get("/files/*", (c) => {  const path = c.req.path;  return c.text(`File: ${path}`);});
// Regex-like patternsapp.get("/user/:id{[0-9]+}", (c) => c.json({ id: c.req.param("id") }));
export default app;

Route Groups

typescript
import { Hono } from "hono";
const app = new Hono();
// Group routesconst api = new Hono();api.get("/users", (c) => c.json([]));api.get("/posts", (c) => c.json([]));
app.route("/api/v1", api);
// Basepathconst app2 = new Hono().basePath("/api/v2");app2.get("/users", (c) => c.json([])); // /api/v2/users
export default app;

Request Handling

typescript
app.post("/submit", async (c) => {  // URL and method  console.log(c.req.url);  console.log(c.req.method);
  // Headers  const auth = c.req.header("Authorization");
  // Query params  const page = c.req.query("page");  const { limit, offset } = c.req.query();
  // Body parsing  const json = await c.req.json();  const text = await c.req.text();  const form = await c.req.formData();  const arrayBuffer = await c.req.arrayBuffer();
  // Parsed body (with validator)  const body = c.req.valid("json");
  return c.json({ received: true });});

Response Types

typescript
app.get("/responses", (c) => {  // Text  return c.text("Hello");
  // JSON  return c.json({ data: "value" });
  // HTML  return c.html("<h1>Hello</h1>");
  // Redirect  return c.redirect("/other", 302);
  // Not Found  return c.notFound();
  // Custom response  return c.body("Raw body", 200, {    "Content-Type": "text/plain",  });
  // Status  return c.json({ error: "Not found" }, 404);
  // Headers  c.header("X-Custom", "value");  return c.json({ ok: true });});

Middleware

typescript
import { Hono } from "hono";
const app = new Hono();
// Global middlewareapp.use("*", async (c, next) => {  console.log(`${c.req.method} ${c.req.url}`);  await next();});
// Path-specific middlewareapp.use("/api/*", async (c, next) => {  const auth = c.req.header("Authorization");  if (!auth) {    return c.json({ error: "Unauthorized" }, 401);  }  await next();});
// Multiple middlewareapp.use("/admin/*", authMiddleware, adminMiddleware);
app.get("/api/data", (c) => c.json({ data: "protected" }));
export default app;

Built-in Middleware

typescript
import { Hono } from "hono";import { cors } from "hono/cors";import { logger } from "hono/logger";import { basicAuth } from "hono/basic-auth";import { bearerAuth } from "hono/bearer-auth";import { compress } from "hono/compress";import { etag } from "hono/etag";import { secureHeaders } from "hono/secure-headers";
const app = new Hono();
// CORSapp.use("*", cors());app.use("/api/*", cors({  origin: "https://example.com",  allowMethods: ["GET", "POST"],}));
// Loggerapp.use("*", logger());
// Basic Authapp.use("/admin/*", basicAuth({  username: "admin",  password: "secret",}));
// Bearer Tokenapp.use("/api/*", bearerAuth({  token: "my-token",}));
// Compressionapp.use("*", compress());
// ETagapp.use("*", etag());
// Security headersapp.use("*", secureHeaders());
export default app;

Validation with Zod

typescript
import { Hono } from "hono";import { zValidator } from "@hono/zod-validator";import { z } from "zod";
const app = new Hono();
const userSchema = z.object({  name: z.string().min(1),  email: z.email(),  age: z.number().min(0).optional(),});
app.post(  "/users",  zValidator("json", userSchema),  (c) => {    const user = c.req.valid("json");    // user is typed and validated    return c.json({ created: user });  });
// Query validationconst querySchema = z.object({  page: z.string().regex(/^\d+$/).optional(),  limit: z.string().regex(/^\d+$/).optional(),});
app.get(  "/items",  zValidator("query", querySchema),  (c) => {    const { page, limit } = c.req.valid("query");    return c.json({ page, limit });  });
export default app;

Context Variables

typescript
import { Hono } from "hono";
type Variables = {  userId: string;  isAdmin: boolean;};
const app = new Hono<{ Variables: Variables }>();
app.use("*", async (c, next) => {  c.set("userId", "123");  c.set("isAdmin", true);  await next();});
app.get("/profile", (c) => {  const userId = c.get("userId");  const isAdmin = c.get("isAdmin");  return c.json({ userId, isAdmin });});
export default app;

Error Handling

typescript
import { Hono } from "hono";import { HTTPException } from "hono/http-exception";
const app = new Hono();
// Throw HTTP errorapp.get("/error", (c) => {  throw new HTTPException(401, { message: "Unauthorized" });});
// Global error handlerapp.onError((err, c) => {  if (err instanceof HTTPException) {    return err.getResponse();  }  console.error(err);  return c.json({ error: "Internal Server Error" }, 500);});
// Not found handlerapp.notFound((c) => {  return c.json({ error: "Not Found" }, 404);});
export default app;

RPC Mode (Type-safe Client)

typescript
// server.tsimport { Hono } from "hono";import { hc } from "hono/client";
const app = new Hono()  .get("/users", (c) => c.json([{ id: 1, name: "Alice" }]))  .post("/users", async (c) => {    const body = await c.req.json();    return c.json({ created: body });  });
export type AppType = typeof app;export default app;
// client.tsimport { hc } from "hono/client";import type { AppType } from "./server";
const client = hc<AppType>("http://localhost:3000");
// Type-safe callsconst res = await client.users.$get();const users = await res.json(); // Typed!
const created = await client.users.$post({  json: { name: "Bob" },});

Common Errors

ErrorCauseFix
Route not foundWrong pathCheck route registration
Body already readDouble parsingRead body once
Validator errorInvalid inputCheck schema definition
Middleware orderWrong executionRegister middleware first

When to Load References

Load references/middleware-list.md when:

  • Complete middleware reference
  • Custom middleware patterns

Load references/openapi.md when:

  • OpenAPI/Swagger integration
  • API documentation generation

來源與署名

來源:secondsky/claude-skills位於plugins/bun/skills/bun-hono-integration提交8837836

授權條款: MIT

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架