bun-hono-integration
Use when building APIs with Hono framework on Bun, including routing, middleware, REST APIs, context handling, or web framework features.
- 0
- Installs
- —
- Rating
- —
- Success rate
- 1
- Files scanned
Security scan
Scan passedNo risky patterns were found in the scanned files.
Content sha256 ecfa7a8edb577187… — run codexguild_scan_skills after installing to verify your local copy.
Static analysis is a first line of defense, not a guarantee. Read the source
SKILL.md
Bun Hono Integration
Hono is a fast, lightweight web framework optimized for Bun.
Quick Start
bun create hono my-app
cd my-app
bun install
bun run dev
Basic Setup
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
import { Hono } from "hono";
const app = new Hono();
// HTTP methods
app.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 methods
app.all("/any", (c) => c.text("Any method"));
// Path parameters
app.get("/users/:id", (c) => {
const id = c.req.param("id");
return c.json({ id });
});
// Multiple parameters
app.get("/posts/:postId/comments/:commentId", (c) => {
const { postId, commentId } = c.req.param();
return c.json({ postId, commentId });
});
// Wildcards
app.get("/files/*", (c) => {
const path = c.req.path;
return c.text(`File: ${path}`);
});
// Regex-like patterns
app.get("/user/:id{[0-9]+}", (c) => c.json({ id: c.req.param("id") }));
export default app;
Route Groups
import { Hono } from "hono";
const app = new Hono();
// Group routes
const api = new Hono();
api.get("/users", (c) => c.json([]));
api.get("/posts", (c) => c.json([]));
app.route("/api/v1", api);
// Basepath
const app2 = new Hono().basePath("/api/v2");
app2.get("/users", (c) => c.json([])); // /api/v2/users
export default app;
Request Handling
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
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
import { Hono } from "hono";
const app = new Hono();
// Global middleware
app.use("*", async (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
await next();
});
// Path-specific middleware
app.use("/api/*", async (c, next) => {
const auth = c.req.header("Authorization");
if (!auth) {
return c.json({ error: "Unauthorized" }, 401);
}
await next();
});
// Multiple middleware
app.use("/admin/*", authMiddleware, adminMiddleware);
app.get("/api/data", (c) => c.json({ data: "protected" }));
export default app;
Built-in Middleware
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();
// CORS
app.use("*", cors());
app.use("/api/*", cors({
origin: "https://example.com",
allowMethods: ["GET", "POST"],
}));
// Logger
app.use("*", logger());
// Basic Auth
app.use("/admin/*", basicAuth({
username: "admin",
password: "secret",
}));
// Bearer Token
app.use("/api/*", bearerAuth({
token: "my-token",
}));
// Compression
app.use("*", compress());
// ETag
app.use("*", etag());
// Security headers
app.use("*", secureHeaders());
export default app;
Validation with Zod
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 validation
const 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
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
import { Hono } from "hono";
import { HTTPException } from "hono/http-exception";
const app = new Hono();
// Throw HTTP error
app.get("/error", (c) => {
throw new HTTPException(401, { message: "Unauthorized" });
});
// Global error handler
app.onError((err, c) => {
if (err instanceof HTTPException) {
return err.getResponse();
}
console.error(err);
return c.json({ error: "Internal Server Error" }, 500);
});
// Not found handler
app.notFound((c) => {
return c.json({ error: "Not Found" }, 404);
});
export default app;
RPC Mode (Type-safe Client)
// server.ts
import { 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.ts
import { hc } from "hono/client";
import type { AppType } from "./server";
const client = hc<AppType>("http://localhost:3000");
// Type-safe calls
const res = await client.users.$get();
const users = await res.json(); // Typed!
const created = await client.users.$post({
json: { name: "Bob" },
});
Common Errors
| Error | Cause | Fix |
|---|---|---|
Route not found | Wrong path | Check route registration |
Body already read | Double parsing | Read body once |
Validator error | Invalid input | Check schema definition |
Middleware order | Wrong execution | Register 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
Files
1- SKILL.md
5e5def3c2b7.3 KB
Agent reviews
0No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.
More from secondsky/claude-skills8
[TODO: Write comprehensive description in third-person. Start with "This skill provides..." or "This skill should be used when..."] [TODO: Add "Use when" scenarios - specific situations where Claude should use this skill] [TODO: Add keywords - technologies, use cases, error messages that should tr
100+ animated React components (Aceternity UI) for Next.js with Tailwind. Use for hero sections, parallax, 3D effects, or encountering animation, shadcn CLI integration errors.
Secure API authentication with JWT, OAuth 2.0, API keys. Use for authentication systems, third-party integrations, service-to-service communication, or encountering token management, security headers, auth flow errors.
Creates comprehensive API changelogs documenting breaking changes, deprecations, and migration strategies for API consumers. Use when managing API versions, communicating breaking changes, or creating upgrade guides.
Verifies API contracts between services using consumer-driven contracts, schema validation, and tools like Pact. Use when testing microservices communication, preventing breaking changes, or validating OpenAPI specifications.
Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers. Use when designing new APIs, reviewing API specifications, or establishing API design standards.
Implements standardized API error responses with proper status codes, logging, and user-friendly messages. Use when building production APIs, implementing error recovery patterns, or integrating error monitoring services.
Builds flexible API filtering and sorting systems with query parameter parsing, validation, and security. Use when implementing search endpoints, building data grids, or creating dynamic query APIs.
Related backend skillsscan passed
Report browser/API/CLI/job/worker/webhook bugs. (gstack)
PostHog integration for server-rendered Astro applications with API routes
Persistent per-project memory for Claude Code (Context Keeper) driven by deterministic Node.js /ck commands: init, save, resume, info, list, forget, and v1-to-v2 migrate, plus a SessionStart hook that injects a compact project brief. Use when context must survive across sessions, saving session stat
This skill should be used when the user asks to "build an MCP server", "create an MCP", "make an MCP integration", "wrap an API for Claude", "expose tools to Claude", "make an MCP app", or discusses building something with the Model Context Protocol. It is the entry point for MCP server development
Guide for upgrading Stripe API versions, webhook endpoints, server-side SDKs, Stripe.js, and mobile SDKs
Mount tRPC as Express middleware with createExpressMiddleware() from @trpc/server/adapters/express. Access Express req/res in createContext via CreateExpressContextOptions. Mount at a path prefix like app.use('/trpc', ...). Avoid global express.json() conflicting with tRPC body parsing for FormData.