Compare

hypequery vs dbt: Transformation Layer or Application Layer?

dbt transforms data inside ClickHouse on a schedule. hypequery serves ClickHouse data to applications at request time. Here is how the two fit together — and when one replaces the other.

Decision type

Architecture and workflow fit

Audience

TypeScript teams building on ClickHouse

Outcome

Choose a path and move into implementation

Job

Runtime queries and typed APIs for application code

Language

TypeScript with schema-generated types

Runs

In your app, in response to user requests

Output

Typed query results, REST endpoints, React hooks

What this page is for

Use this page when the real question is how one tool changes the shape of your ClickHouse application code, not just which syntax looks nicer.

What this page is not

It is not a broad ecosystem roundup. It stays narrow on the tradeoff a ClickHouse-heavy TypeScript team is actually deciding.

Recommended next move

If the tradeoff already looks clear, stop reading comparisons and test the fit against one real query in your own schema.

Dimension
hypequery
Alternative
Job
Runtime queries and typed APIs for application code
Scheduled SQL transformations inside the warehouse
Language
TypeScript with schema-generated types
SQL with Jinja templating
Runs
In your app, in response to user requests
On a schedule or trigger via dbt run
Output
Typed query results, REST endpoints, React hooks
Materialised tables and views in ClickHouse

dbt and hypequery both sit on top of ClickHouse, both live in version control, and both exist so analytics logic doesn't end up as untracked SQL strings scattered across the codebase. That's about where the similarity ends — they run at different times, in different places, for different people.

dbt is a transformation layer: it runs SQL on a schedule inside ClickHouse and materialises the results as tables and views. hypequery is an application layer: it runs typed queries from your TypeScript code at request time and exposes them as APIs and React hooks.

Teams end up comparing them because both show up when you search "analytics layer on ClickHouse." This page separates the two jobs so you can figure out which one your stack actually needs — or whether it's both.

What dbt does

dbt compiles SQL SELECT statements into ClickHouse-compatible SQL, runs them via the dbt-clickhouse adapter, and materialises the results as tables or views. Its strengths:

  • Versioned, documented, testable SQL transformations
  • Dependency ordering between models and incremental loads
  • A workflow data teams already know from the warehouse world

Its relationship with ClickHouse works, but it's not seamless: no transactions, append-optimised storage, and MergeTree engine semantics mean some dbt patterns that are clean on Postgres or Snowflake need extra care here.

The important part: dbt runs on a schedule or trigger. It's not in the request path. It can't answer a user's dashboard filter or a tenant-scoped API call — that was never the job.

What hypequery does

hypequery handles the request path instead. Your application needs to query ClickHouse in response to user actions, with runtime parameters, and it needs the results typed correctly:

  • Generated types from your live ClickHouse schema — including the tables dbt materialises — with correct runtime mappings (DateTime → string, UInt64 → string, NullableT | null)
  • A composable query builder for filters, date ranges, aggregations, and tenant scoping decided at runtime
  • Typed REST endpoints via @hypequery/serve, with input validation and generated OpenAPI docs
  • React hooks that consume the same typed contract in dashboards

The honest comparison

dbthypequery
JobTransform data inside ClickHouseQuery and serve data to applications
RunsOn a schedule (dbt run)At request time, in your app
LanguageSQL + JinjaTypeScript
ConsumersAnalysts, BI tools, downstream modelsProduct code, APIs, React components
Type safetyData tests on model outputCompile-time types generated from schema
Schema roleDefines and materialises tablesIntrospects whatever exists
In the request pathNoYes

Complementary more than competitive

The most common production setup uses both, with a clean handoff between them:

  1. Raw events land in ClickHouse
  2. dbt models them into clean analytics tables on a schedule
  3. hypequery introspects those tables, generates types, and serves them to the application as typed queries and endpoints

Because hypequery generates types from the live schema, a dbt model change followed by a re-run of generate immediately surfaces any breakage in application code — at compile time, not in production. That's exactly the drift problem teams run into when the two layers are wired together by hand.

For a deeper treatment of where the transformation boundary should sit, read TypeScript vs dbt for ClickHouse.

When dbt alone is enough

  • Your ClickHouse consumers are analysts and BI tools, not application code
  • Nothing queries ClickHouse at request time
  • Your team is SQL-first and the output of analytics is reports, not product features

When hypequery alone is enough

  • Your transformations are simple enough for ClickHouse materialized views to handle
  • The main consumer of ClickHouse is your TypeScript application
  • Maintaining a separate transformation project would be overhead for a handful of tables that exist only to feed application APIs

When you want both

  • Raw event volumes need real modelling before they are queryable
  • A data team owns transformation logic while product engineers own application features
  • You want typed, compile-time-checked application access to the tables dbt produces

Getting started with hypequery

The quick start covers pointing hypequery at your ClickHouse — including dbt-materialised tables — generating types, and serving your first typed endpoint. The ClickHouse TypeScript guide covers the broader workflow.

Decision checkpoint

If the tradeoff is already clear, move into implementation

Most teams do not need another round of comparison content after this point. The better test is whether the workflow holds up on your own schema and your own query complexity.

Related content

Continue into implementation

FAQ

Does dbt support ClickHouse?

Yes — the dbt-clickhouse adapter covers the common materialisation patterns, though ClickHouse semantics (no transactions, MergeTree engines) mean some dbt patterns from Postgres do not translate directly.

Do hypequery and dbt compete?

Mostly no. dbt prepares data inside ClickHouse; hypequery serves it to applications with type safety. A common stack is dbt for modelling raw events into analytics tables and hypequery for querying those tables from product code.

When would hypequery replace dbt?

If your only use of dbt is preparing a handful of tables that feed application APIs, a typed TypeScript layer querying the source tables directly — or ClickHouse materialized views — can be simpler than maintaining a separate transformation project.

Next step

Move from evaluation into a typed ClickHouse workflow

Generate schema types, define your first reusable query, and decide whether it should run locally or over HTTP.