Unrag
Frameworks

Hono Integration

Using Unrag with Hono for lightweight, fast APIs on Node.js or edge runtimes.

Hono is a lightweight web framework that works across Node.js, Bun, Deno, and Cloudflare Workers. When running on Node.js or Bun with standard Postgres drivers, Unrag integrates seamlessly. For edge runtimes, you'll need compatible database drivers.

Basic setup on Node.js

On Node.js or Bun, Unrag's default adapters work out of the box:

import { Hono } from "hono";
import { createUnragEngine } from "@unrag/config";

const app = new Hono();

app.get("/api/search", async (c) => {
  const query = c.req.query("q")?.trim();
  
  if (!query) {
    return c.json({ error: "Missing query parameter" }, 400);
  }
  
  const engine = createUnragEngine();
  const result = await engine.retrieve({ query, topK: 10 });
  
  return c.json({
    query,
    results: result.chunks.map((chunk) => ({
      id: chunk.id,
      content: chunk.content,
      source: chunk.sourceId,
      score: chunk.score,
    })),
  });
});

app.post("/api/ingest", async (c) => {
  const body = await c.req.json().catch(() => null);
  
  if (!body?.sourceId || !body?.content) {
    return c.json({ error: "Missing sourceId or content" }, 400);
  }
  
  const engine = createUnragEngine();
  const result = await engine.ingest({
    sourceId: body.sourceId,
    content: body.content,
    metadata: body.metadata ?? {},
  });
  
  return c.json({
    documentId: result.documentId,
    chunkCount: result.chunkCount,
  });
});

export default app;

Run with Node.js, Bun, or Deno (with Node compatibility):

# With Bun
bun run --hot src/index.ts

# With Node.js (using tsx)
npx tsx src/index.ts

Input validation with Zod

Hono works well with Zod for request validation:

import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
import { createUnragEngine } from "@unrag/config";

const app = new Hono();

const searchSchema = z.object({
  q: z.string().min(2).max(500),
  topK: z.coerce.number().min(1).max(50).default(10),
  scope: z.string().optional(),
});

app.get(
  "/api/search",
  zValidator("query", searchSchema),
  async (c) => {
    const { q, topK, scope } = c.req.valid("query");
    
    const engine = createUnragEngine();
    const result = await engine.retrieve({
      query: q,
      topK,
      scope: scope ? { sourceId: scope } : undefined,
    });
    
    return c.json({
      query: q,
      results: result.chunks,
      meta: { embeddingModel: result.embeddingModel },
    });
  }
);

const ingestSchema = z.object({
  sourceId: z.string().min(1),
  content: z.string().min(1),
  metadata: z.record(z.unknown()).optional(),
});

app.post(
  "/api/ingest",
  zValidator("json", ingestSchema),
  async (c) => {
    const { sourceId, content, metadata } = c.req.valid("json");
    
    const engine = createUnragEngine();
    const result = await engine.ingest({ sourceId, content, metadata });
    
    return c.json(result);
  }
);

Edge runtime considerations

Unrag's default adapters use the pg driver, which relies on Node.js APIs not available in edge runtimes (Cloudflare Workers, Vercel Edge).

If you're deploying to edge, you have options:

Middleware for common patterns

Hono's middleware system lets you add cross-cutting concerns:

import { Hono } from "hono";
import { cors } from "hono/cors";
import { logger } from "hono/logger";
import { timing } from "hono/timing";

const app = new Hono();

// Enable CORS for frontend access
app.use("/api/*", cors());

// Log requests
app.use("*", logger());

// Add server timing headers
app.use("*", timing());

// Your routes
app.get("/api/search", async (c) => {
  // ...
});

Error handling

Wrap operations in try-catch and return appropriate responses:

import { HTTPException } from "hono/http-exception";

app.get("/api/search", async (c) => {
  const query = c.req.query("q");
  
  if (!query) {
    throw new HTTPException(400, { message: "Missing query" });
  }
  
  try {
    const engine = createUnragEngine();
    const result = await engine.retrieve({ query, topK: 10 });
    return c.json(result);
  } catch (error) {
    console.error("Search failed:", error);
    throw new HTTPException(500, { message: "Search failed" });
  }
});

// Global error handler
app.onError((err, c) => {
  if (err instanceof HTTPException) {
    return c.json({ error: err.message }, err.status);
  }
  return c.json({ error: "Internal server error" }, 500);
});

Deployment patterns

Hono apps can deploy to many platforms:

  • Bun: bun run src/index.ts
  • Node.js: Use @hono/node-server adapter
  • Deno: deno run --allow-net src/index.ts
  • Cloudflare Workers: Use wrangler deploy (edge-compatible driver needed)
  • AWS Lambda: Use @hono/aws-lambda adapter

For Node.js deployments where Unrag works best, the integration is straightforward. For edge deployments, plan for the driver compatibility issues ahead of time.

On this page

RAG handbook banner image

Free comprehensive guide

Complete RAG Handbook

Learn RAG from first principles to production operations. Tackle decisions, tradeoffs and failure modes in production RAG operations

The RAG handbook covers retrieval augmented generation from foundational principles through production deployment, including quality-latency-cost tradeoffs and operational considerations. Click to access the complete handbook.