ClickHouse TypeScript

Type-safe ClickHouse queries, APIs, and analytics backends in TypeScript

hypequery helps teams use ClickHouse with TypeScript without hand-written schema interfaces, raw SQL drift, or runtime type mismatches. Generate schema types, define reusable analytics queries, and expose the same logic over HTTP.

Core benefit

Generated schema types

Execution model

Local or HTTP

Best fit

Analytics-heavy TypeScript apps

ClickHouse types do not map cleanly to JavaScript

DateTime values come back as strings, UInt64 values often need to stay strings, and Nullable columns return null. If you hand-write TypeScript interfaces, TypeScript trusts the wrong types.

Raw SQL strings do not scale across a product codebase

The same analytics query ends up duplicated in API routes, background jobs, dashboards, and internal tools. Refactors become fragile because the query contract is spread across string literals.

Most teams end up rebuilding the same analytics layer

Once a ClickHouse project grows, teams want generated schema types, reusable query definitions, typed APIs, and a clean way to share analytics logic between backend and frontend.

How hypequery helps

A ClickHouse TypeScript workflow built for reusable analytics

Instead of hand-writing TypeScript interfaces and duplicating raw SQL strings, you generate schema types from ClickHouse and define analytics queries once. Those definitions can run locally in-process or be served over HTTP with the same types.

  • Generate TypeScript schema types from your live ClickHouse database
  • Build type-safe ClickHouse queries without hand-maintained interfaces
  • Reuse the same analytics definitions across APIs, jobs, and dashboards
  • Expose typed HTTP endpoints with request and response schemas
  • Keep ClickHouse runtime types aligned with your TypeScript codebase

Step 1

Generate schema types from ClickHouse

npx hypequery generate --output analytics/schema.ts

This is where the ClickHouse TypeScript workflow becomes reliable. Runtime types like `DateTime`, `UInt64`, `Nullable`, and `Decimal` get mapped correctly instead of being guessed.

Step 2

Define typed ClickHouse queries once

hypequery lets you model analytics queries in TypeScript and reuse them across product surfaces. That means the same query definition can power a dashboard, an API route, a job, or an internal tool without duplicating logic.

This is the difference between “ClickHouse client in TypeScript” and a real ClickHouse analytics backend in TypeScript. You are not just running queries. You are defining typed contracts that can be reused safely.

If your team is comparing options, read hypequery vs @clickhouse/client and hypequery vs Kysely after this page.

const { query, serve } = initServe({
  context: () => ({ db }),
});

const revenueByDay = query({
  input: z.object({
    startDate: z.string(),
    endDate: z.string(),
  }),
  query: async ({ ctx, input }) => {
    return ctx.db
      .table('orders')
      .where('created_at', 'gte', input.startDate)
      .where('created_at', 'lte', input.endDate)
      .groupBy(['day'])
      .sum('total', 'revenue')
      .execute();
  },
});

const api = serve({
  queries: { revenueByDay },
});

api.route('/revenue-by-day', api.queries.revenueByDay, { method: 'POST' });

Why teams search for this

Common ClickHouse TypeScript problems this page should solve

ClickHouse query builder for TypeScript

If you want a ClickHouse query builder with real TypeScript support, the key question is not just syntax. It is whether the builder understands ClickHouse runtime types and can be reused across your app.

ClickHouse types in TypeScript

DateTime, UInt64, Decimal, and Nullable columns are where most silent bugs start. If that is your main pain point, read the type problem guide.

Reusable analytics APIs in TypeScript

Teams often start with raw queries and then realize they need typed APIs, internal analytics services, or OpenAPI docs on top. hypequery is optimized for that step-up in complexity.

Alternatives to hand-written query types

Hand-maintained interfaces drift. Generated schema types plus typed query definitions remove that drift from the system instead of relying on discipline alone.

Further reading

Compare approaches and go deeper

Next step

Start with the ClickHouse TypeScript quick path

Generate schema types, define your first typed query, and then decide whether you want to run it locally or expose it over HTTP.