Hono

Edge-ready middleware for Hono. Works with Cloudflare Workers, Deno, Bun, and Node.js.

Installation

Terminal
npm install @tryhamster/gerbil hono

Quick Start

index.ts
01import { Hono } from "hono";
02import { gerbil } from "@tryhamster/gerbil/hono";
03
04const app = new Hono();
05
06// Create and mount AI routes
07const aiRoutes = await gerbil({ model: "qwen3.5-0.8b" })();
08app.route("/ai", aiRoutes);
09
10export default app;

Available Endpoints

MethodEndpointDescription
POST/generateGenerate text
POST/streamStream text (SSE)
POST/jsonStructured output
POST/embedEmbeddings
GET/infoModel info

Configuration

config.ts
01import { gerbil } from "@tryhamster/gerbil/hono";
02
03const aiRoutes = await gerbil({
04 model: "qwen3.5-0.8b",
05 device: "auto", // "auto" | "webgpu"
06 dtype: "q4", // quantization
07 cache: true, // response caching
08})();
09
10// Generation options (maxTokens, temperature, system, ...) are passed
11// per request in the POST body.

Streaming Responses

streaming.ts
01import { Hono } from "hono";
02import { streamSSE } from "hono/streaming";
03import { stream as streamText } from "@tryhamster/gerbil";
04
05const app = new Hono();
06
07app.post("/stream", async (c) => {
08 const { prompt } = await c.req.json();
09
10 return streamSSE(c, async (stream) => {
11 for await (const token of streamText(prompt)) {
12 await stream.writeSSE({
13 data: JSON.stringify({ token }),
14 });
15 }
16 await stream.writeSSE({
17 data: JSON.stringify({ done: true }),
18 });
19 });
20});

Custom Routes

custom.ts
01import { Hono } from "hono";
02import { generate } from "@tryhamster/gerbil";
03
04const app = new Hono();
05
06// Custom summarize endpoint (the model loads on first use)
07app.post("/summarize", async (c) => {
08 const { content } = await c.req.json();
09
10 const result = await generate(
11 `Summarize: ${content}`,
12 { maxTokens: 150 }
13 );
14
15 return c.json({ summary: result.text });
16});
17
18// Custom translate endpoint
19app.post("/translate", async (c) => {
20 const { text, to } = await c.req.json();
21
22 const result = await generate(
23 `Translate to ${to}: ${text}`,
24 { maxTokens: 200 }
25 );
26
27 return c.json({ translation: result.text });
28});
29
30export default app;

Middleware

middleware.ts
01import { Hono } from "hono";
02import { cors } from "hono/cors";
03import { logger } from "hono/logger";
04import { bearerAuth } from "hono/bearer-auth";
05import { gerbil } from "@tryhamster/gerbil/hono";
06
07const app = new Hono();
08
09// Apply middleware
10app.use("*", logger());
11app.use("/ai/*", cors());
12app.use("/ai/*", bearerAuth({ token: process.env.API_TOKEN }));
13
14// Mount AI routes
15const aiRoutes = await gerbil({ model: "qwen3.5-0.8b" })();
16app.route("/ai", aiRoutes);
17
18export default app;

Bun

bun.ts
01// index.ts
02import { Hono } from "hono";
03import { gerbil } from "@tryhamster/gerbil/hono";
04
05const app = new Hono();
06
07const aiRoutes = await gerbil({ model: "qwen3.5-0.8b" })();
08app.route("/ai", aiRoutes);
09
10export default {
11 port: 3000,
12 fetch: app.fetch,
13};
14
15// Run with: bun run index.ts

Deno

deno.ts
01// main.ts
02import { Hono } from "npm:hono";
03import { gerbil } from "npm:@tryhamster/gerbil/hono";
04
05const app = new Hono();
06
07const aiRoutes = await gerbil({ model: "qwen3.5-0.8b" })();
08app.route("/ai", aiRoutes);
09
10Deno.serve({ port: 3000 }, app.fetch);
11
12// Run with: deno run --allow-net --allow-read main.ts

Error Handling

error-handling.ts
01import { Hono } from "hono";
02import { HTTPException } from "hono/http-exception";
03import { gerbil } from "@tryhamster/gerbil/hono";
04
05const app = new Hono();
06
07// Global error handler
08app.onError((err, c) => {
09 console.error(err);
10
11 if (err instanceof HTTPException) {
12 return c.json({ error: err.message }, err.status);
13 }
14
15 return c.json({ error: "Internal server error" }, 500);
16});
17
18// AI routes: route errors return JSON { error } with status 500;
19// the global handler above catches anything thrown outside them.
20const aiRoutes = await gerbil({ model: "qwen3.5-0.8b" })();
21
22app.route("/ai", aiRoutes);
23
24export default app;