Compare

hypequery vs Kysely: Two Different Bets on Type Safety

Kysely is an excellent TypeScript query builder. On ClickHouse, the tradeoffs change. Here's where hypequery fits and what each tool optimizes for.

Decision type

Architecture and workflow fit

Audience

TypeScript teams building on ClickHouse

Outcome

Choose a path and move into implementation

Best for

ClickHouse-first TypeScript analytics

Schema source

Generated from live ClickHouse schema

Application layer

Query builder, HTTP serving, OpenAPI, React hooks

What this page is for

Use this page when the question is not just syntax, but how a tool fits a ClickHouse-heavy application architecture.

What this page is not

It is not a generic ecosystem roundup. The comparison is intentionally focused on teams building reusable analytics behavior in TypeScript.

Recommended next move

If hypequery looks like the right fit, move directly into the quick start and the ClickHouse TypeScript guide.

Dimension
hypequery
Alternative
Best for
ClickHouse-first TypeScript analytics
General SQL query building, especially Postgres
Schema source
Generated from live ClickHouse schema
Usually hand-maintained TypeScript interfaces
Application layer
Query builder, HTTP serving, OpenAPI, React hooks
Query builder only
Back to comparisons

Kysely is one of the best TypeScript query builders available. If you're on Postgres, MySQL, or SQLite, it's a serious option, possibly the best one. It's composable, well-typed, has an active community, and a growing ecosystem of dialects.

For the broader framing behind this comparison, start with the ClickHouse TypeScript pillar page. If your real question is how to build a reusable analytics layer, pair it with ClickHouse analytics.

If you're on ClickHouse, the picture changes. This post explains why and where hypequery fits in.

The thing Kysely gets right

Kysely's core insight is that your database schema should drive your TypeScript types, not the other way around. You define an interface that mirrors your tables, pass it as a type parameter to the query builder, and from that point on, the type checker knows what every column is named, what type it holds, and whether it's nullable.

This is excellent. The query builder is fully typed. Autocomplete works. Type errors surface at compile time. Renaming a column in the interface immediately flags every query that references it.

The gap is the interface itself: you write it by hand.

The ClickHouse problem

ClickHouse isn't a general-purpose relational database. It's a columnar analytics database with its own type system and its own conventions around how data is actually returned over the wire.

DateTime in ClickHouse doesn't come back as a JavaScript Date. It comes back as a string. UInt64 can exceed JavaScript's safe integer range, so it comes back as a string too. Nullable(T) maps to T | null, but only if you know to write it that way.

If you're hand-writing the Kysely interface for a ClickHouse table, you have to know all of this. Get it wrong and TypeScript will trust you. The type can say Date and the runtime can still give you a string.

Kysely does have a community ClickHouse dialect. It handles the connection. It does not solve the runtime type mapping problem for you.

That runtime mapping gap is exactly what the ClickHouse TypeScript pillar and the type-problem article are trying to make explicit.

What hypequery does differently

hypequery generates the interface from your live schema.

The CLI connects to your ClickHouse instance, reads the schema, and emits a TypeScript file that maps each ClickHouse type to its actual runtime equivalent. DateTime becomes string. UInt64 becomes string. Nullable(String) becomes string | null.

When the schema changes, rerun the generator. You don't maintain the interface manually.

Beyond the query builder

This is where the two tools diverge more sharply.

Kysely is a query builder. A very good query builder. It produces typed SQL that gets sent to your database. What you do with the results, how you expose them, how you share queries across contexts, how you document the endpoints, is out of scope.

hypequery is designed for a specific use case: building an analytics layer that needs to work across multiple consumers. The same query definition can run inline, be exposed as an HTTP endpoint via @hypequery/serve, be consumed in React, or be called by another service.

Kysely has no equivalent of this end-to-end analytics layer. It's not trying to. The use case is different.

What you give up with hypequery

Kysely's ecosystem is much larger. Plugins, community dialects, adapters, and migration tooling have been built for years. hypequery is younger and much smaller.

Kysely's query builder is more compositionally flexible. Because Kysely is database-agnostic, its API handles a wider range of SQL patterns. hypequery's builder is ClickHouse-specific and focused on analytics query patterns.

Kysely works across databases. If your stack includes Postgres for transactional data and ClickHouse for analytics, Kysely can span both. hypequery is ClickHouse-only.

The honest summary

| | Kysely | hypequery | |---|---|---| | Database support | Postgres, MySQL, SQLite, ClickHouse via community dialect | ClickHouse only | | Type generation | Manual interface definition | Generated from live schema | | ClickHouse type mapping | You manage it | Handled by the CLI | | Query builder flexibility | Very high | Analytics-focused | | HTTP layer | Not included | @hypequery/serve | | React integration | Not included | @hypequery/react | | OpenAPI docs | Not included | Supported from schemas and metadata | | Community size | Large and growing | Smaller and earlier |

If you're on Postgres and want the best TypeScript query builder available, use Kysely.

If you're on ClickHouse and need type safety that reflects ClickHouse's actual runtime behavior, plus a path from queries to APIs, hypequery is the more direct route.

If you're on ClickHouse and have simple needs and don't mind writing the type interface by hand, Kysely with the community dialect is still viable. The tradeoff is explicit: you own the type accuracy.

Getting started with hypequery

If you're evaluating both tools, start with the Quick Start and then compare the generated schema flow against your current hand-written interfaces. After that, read ClickHouse analytics if the bigger question is how those queries get reused across APIs, dashboards, and services.

Decision checkpoint

If the tradeoff is already clear, move into implementation

Teams usually do not need more comparison content after this point. The faster path is to generate schema types and build one real query against your own ClickHouse schema.

Related content

Continue into implementation

FAQ

Can Kysely work with ClickHouse?

Yes, but you still need to handle ClickHouse-specific runtime type mappings and application-level reuse yourself.

When is hypequery a better fit?

Use hypequery when ClickHouse is powering dashboards, APIs, jobs, or SaaS analytics where the same typed query contract needs to be reused.

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.