A full-stack tutorial for building a SaaS analytics API: generate TypeScript types from your ClickHouse schema, write typed queries, define metrics once, serve zod-validated REST routes with OpenAPI docs, and consume them from React with inferred types.
ReplacingMergeTree deduplicates at merge time, so queries can see duplicates until merges run. Learn when the FINAL keyword is the right fix, what it costs, and when the argMax or LIMIT BY patterns are better — with typed TypeScript examples.
A working tour of ClickHouse's array toolkit from TypeScript: groupArray to collect rows into arrays, arrayMap and arrayFilter to transform them, ARRAY JOIN to flatten them back — with typed hypequery examples throughout.
A step-by-step primer on turning a ClickHouse query into a governed, typed REST API with @hypequery/serve — context, zod input validation, OpenAPI docs, auth hooks, and one query definition callable in-process or over HTTP.
How WITH clauses actually behave in ClickHouse (inlined, not materialized), and how to build typed CTEs in TypeScript with hypequery's .withCTE() — including builder-as-subquery composition, cohort retention joins, and reusable filtered subsets.
ORMs manage entities, relations, and migrations for transactional databases. Query builders construct typed SQL. Here's why that distinction matters for ClickHouse, and where hypequery deliberately sits.
LIMIT BY is ClickHouse's built-in answer to top-N-per-group: latest 3 events per user, top 5 products per category. Learn how it works, how it differs from LIMIT and row_number(), and how to write it in TypeScript with hypequery's native .limitBy().
No mature ORM exists for ClickHouse, and the architecture explains why. Here's what actually exists for TypeScript teams — the official client, typed query builders, SQL tag libraries — and what to use instead.
How to use row_number(), rank(), dense_rank(), and lagInFrame() in ClickHouse, and how to run window functions from a type-safe TypeScript query builder with hypequery.