> Every UQL docs page, as Markdown: https://uql-orm.dev/llms.txt
> The same docs over MCP: https://uql-orm.dev/mcp
> Before writing UQL code, read the skill: https://uql-orm.dev/.well-known/agent-skills/uql-orm/SKILL.md

# Hono

> Query UQL from your Hono routes, and optionally mount entity CRUD with the fetch handler.

Source: https://uql-orm.dev/hono

Your Hono routes query the pool directly. If you also want CRUD routes for many entities without writing them, mount the [HTTP handler](https://uql-orm.dev/http.md). Hono is fetch-native, so nothing else is needed.

## Your own routes

```ts
import { Hono } from 'hono';
import { Post } from './shared/models/index.js';
import { pool } from './uql.config.js';

const app = new Hono();

app.get('/posts', async (c) => {
  const posts = await pool.findMany(Post, {
    $where: { published: true },
    $limit: 20,
  });
  return c.json(posts);
});

export default app; // Bun and Workers; on Node, serve(app) from @hono/node-server
```

[The pool](https://uql-orm.dev/http.md#the-pool) shows the `uql.config.ts` it comes from. Run several writes together in [`pool.transaction`](https://uql-orm.dev/querying/transactions.md).

## Auto-generated CRUD

Mount the handler under a prefix, beside your own routes:

```ts
import { cors } from 'hono/cors';
import { createFetchHandler } from 'uql-orm/http';
import { Post, User } from './shared/models/index.js';

const handler = createFetchHandler({ pool, include: [User, Post] });

app.use('*', cors());
app.mount('/api', handler);
```

`.mount()` strips the prefix and forwards every method, so this serves the [wire protocol](https://uql-orm.dev/http.md#wire-protocol), [`QUERY`](https://uql-orm.dev/http.md#http-query-rfc-10008) included. An unknown route under `/api` is a `404` from the handler, not passed on to later routes.

Hooks and tenant scoping are the handler’s: see [hooks](https://uql-orm.dev/http.md#authorization-hooks) and [`getContext`](https://uql-orm.dev/http.md#tenant-scoping). Their `context` is the web `Request`.

Hono’s `hc` client sees only chained routes, not mounted ones. Use the [browser client](https://uql-orm.dev/browser.md) for the CRUD routes.

## Cloudflare D1

A [D1](https://uql-orm.dev/cloudflare-d1.md) binding arrives with each request, and `.mount()` hands the handler a bare `Request` with no way back to `c.env`. Route it yourself and pass the prefix as `basePath`:

```ts
import { Hono } from 'hono';
import { D1QuerierPool } from 'uql-orm/d1';
import { createFetchHandler } from 'uql-orm/http';
import { Post, User } from './shared/models/index.js';

const app = new Hono<{ Bindings: { DB: D1Database } }>();

app.all('/api/*', (c) => {
  const handler = createFetchHandler({
    pool: new D1QuerierPool(c.env.DB),
    include: [User, Post],
    basePath: '/api',
  });
  return handler(c.req.raw);
});
```

D1 has no transactions, and the handler runs every write in one, so the write routes answer `400` on D1. Reads work. Write through your own routes instead.
