ClickHouse tRPC
Use hypequery ClickHouse queries as tRPC procedures
tRPC gives you end-to-end type safety from server to React client. hypequery gives you end-to-end type safety from ClickHouse schema to TypeScript. Combining them means your analytics procedures are typed all the way from the database column definition to the component that renders the chart.
Integration layer
tRPC procedure
Type source
ClickHouse schema
Best for
Full-stack TypeScript apps
tRPC doesn't query ClickHouse natively — you lose types immediately
tRPC procedures delegate to whatever data layer you choose. When that layer is raw @clickhouse/client, the response is untyped. You end up casting to any or manually annotating shapes that should be inferred from the ClickHouse schema itself.
ClickHouse analytics need a bridge into the tRPC router model
A tRPC procedure expects validated input and a typed return value. ClickHouse queries produce rows with column names and ClickHouse-native types — DateTime, UInt64, Nullable. Reconciling the two by hand means schema definitions in three places: the database, the query, and the tRPC output type.
Multi-tenant analytics need tenant context from tRPC ctx — wiring it manually is repetitive
Every analytics procedure needs to read tenantId from the tRPC context and inject it into the ClickHouse WHERE clause. Without a shared pattern, each procedure implements its own auth extraction and tenant filtering independently.
How it fits together
Call hypequery inside tRPC procedures — types flow through automatically
hypequery query builder methods return TypeScript types inferred directly from your ClickHouse schema. When you call those methods inside a tRPC procedure, the return type of the procedure is inferred automatically — no manual annotation, no casting.
- Run npx @hypequery/cli generate to produce schema.ts from your live ClickHouse instance
- Import db (the typed query builder) and call it inside a tRPC procedure
- Pass ctx.tenantId from tRPC context directly into the WHERE clause
- tRPC infers the procedure output type from the hypequery return value
- useQuery() on the client gets the same inferred type — DateTime columns as string, UInt64 as string, Nullable as T | null
tRPC procedure
Typed ClickHouse query inside a tRPC router
Tenant context flows from tRPC ctx to the ClickHouse WHERE clause. The procedure output type is inferred from the query — no manual annotation needed.
Full stack
From ClickHouse schema to React hook — one type chain, no casting
The hypequery query builder produces column types from your schema. Those types become the tRPC procedure output. tRPC propagates them to the React client. The component that renders the chart knows the exact shape of every row without any manual type annotation in the middle.
This pattern scales to multi-tenant apps cleanly. Each procedure reads tenantId from the tRPC context once — defined in the context factory when you create the tRPC instance — and passes it to the ClickHouse query. No per-procedure auth logic.
If you need HTTP access from outside the tRPC client (mobile apps, third-party consumers), pair this with @hypequery/serve to expose the same query as a REST endpoint alongside the tRPC router.
Full stack example
tRPC procedure and the React hook that consumes it
The component does not import any ClickHouse types. Everything is inferred through tRPC from the hypequery query definition.
Where teams usually get stuck
Questions teams ask
ClickHouse tRPC router
Adding ClickHouse queries to a tRPC router is straightforward: call the hypequery query builder inside your procedure and return the result. tRPC infers the output type from whatever the async function returns.
tRPC analytics backend TypeScript
A tRPC analytics backend needs validated inputs, typed ClickHouse responses, and tenant context injection. hypequery handles the ClickHouse side — you wire the tRPC context once and every procedure inherits it.
ClickHouse typed procedures
ClickHouse column types (DateTime, UInt64, Nullable) map to TypeScript types through hypequery schema generation. The procedure output type is inferred — you never write a manual response interface for a ClickHouse query again.
tRPC ClickHouse query builder
Using a query builder inside tRPC procedures keeps analytics logic reusable. The same hypequery query can run inside a tRPC procedure, a server component, or a cron job — it's not bound to the HTTP layer.
Further reading
Go deeper where it actually helps
ClickHouse TypeScript
The foundation: schema-generated types and the query builder API.
Open guide
ClickHouse React
Typed React hooks for ClickHouse analytics — the browser-side counterpart to tRPC procedures.
Open guide
ClickHouse REST API
Expose the same queries as typed REST endpoints alongside your tRPC router.
Open guide
ClickHouse Next.js
Integrate ClickHouse analytics into Next.js App Router with server components and API routes.
Open guide
Next step
Generate your schema, then call the query builder inside a tRPC procedure
Run npx @hypequery/cli generate to produce typed schema bindings from your ClickHouse instance. After that, the query builder is ready to call from any tRPC procedure — types flow through automatically.