Effect ClickHouse
@maple-dev/effect-clickhouse builds ClickHouse SQL from typed TypeScript. You describe a
table once, and the builder infers column types, output row shapes, and join accessors from
it. Queries are immutable values — every method returns a new query — and nothing touches the
network: the end product is a CompiledQuery holding a SQL string plus a typed decoder. You
bring your own ClickHouse client.
Is this for your project?
Use the builder when you want typed ClickHouse SELECT queries, reusable query definitions, and runtime result decoding in TypeScript. It works with an ordinary async application as well as an Effect application. The database client remains your choice.
You do not need a Maple account, Maple's schema, or tenant columns. Tenant analysis is an optional feature for applications that share tables between tenants.
The root builder does not manage connections, create tables, run migrations, insert rows, or provide an ORM. It does not validate SQL against a live server, choose query plans, enforce authorization, or supply retries. Existing ClickHouse tables and your executor own those responsibilities. Getting started covers npm installation and building from source.
Start here
- Compile and decode offline with one complete file.
- Run a real query against
system.numbers, without creating a table. - Adapt a recipe to your own schema.
- Benchmark a change with a fixed workload and saved baseline.
- Consult Troubleshooting if installation or results differ from expectations.
The named complete examples are extracted from Markdown, typechecked, and exercised by
check-doc-examples.mjs. Focused behavior tests also live in
src/docs-examples.test.ts. Client execution requires a server;
the offline checks verify SQL construction and decoding, not database execution plans.
Guides
Roughly in reading order.
| Guide | What it covers |
|---|---|
| Getting started | Install, define a table, build → compile → decode |
| Tables and column types | table(), the column-type constructors, Map/Array/Nullable |
| Building queries | select, where, groupBy, orderBy, limit, format, immutability |
| Expressions and conditions | Comparisons, arithmetic, optional predicates, aggregates |
| Joins and subqueries | The join family, fromQuery, correlated subqueries |
| Unions and CTEs | unionAll, fromUnion, withCTE |
| Params and compilation | param.*, how values reach the SQL, CompiledQuery |
| Decoding results | rowSchema, decodeRows, decodeFirstRow, decode errors |
| Running a query | Executing the SQL with a real client, wire settings, SETTINGS |
| Benchmarking | Define suites, measure baseline/candidate runs, verify results, and compare budgets |
| Agent benchmark playbook | Repeatable optimization workflow and evidence checklist |
| Tenant scoping | tenantScope, what marks a query scoped, crossTenant() |
| Extending the DSL | defineFn, raw escape hatches, handwritten SQL |
Reference
-
Recipes — complete examples for everyday queries.
-
Troubleshooting — common failures and sharp edges.
-
API reference — the full export catalog by module, plus error types.
Entry points
| Import | Contents |
|---|---|
@maple-dev/effect-clickhouse | Curated public API — from, compile, param, expression helpers, and ClickHouse functions under friendly names (min, max, count, quantile, …) |
@maple-dev/effect-clickhouse/types | Column-type constructors (string, uint64, dateTime, map, array, nullable, …) and the CH* type descriptors |
@maple-dev/effect-clickhouse/expr | Kitchen-sink namespace: every expression helper plus all ClickHouse functions under their raw names (min_, toString_, dynamicColumn, not, …) |
@maple-dev/effect-clickhouse/sql | The low-level SqlFragment AST (raw, ident, compile, …) for hand-rolling fragments |
@maple-dev/effect-clickhouse/benchmark | Driver-free suite definitions, runner, report schemas, and comparisons |
@maple-dev/effect-clickhouse/benchmark/http | ClickHouse HTTP transport, environment configuration, and query-log collection |
@maple-dev/effect-clickhouse/benchmark/cli | runCli(args) for embedding the bundled ch-bench commands |
The root barrel is curated, not exhaustive — see the reference for what lives only on a subpath.
Query benchmarks
The optional @maple-dev/effect-clickhouse/benchmark entry point and bundled
ch-bench CLI measure real queries, compare fixed workloads, and save evidence.
See Benchmarking and the
agent playbook. The root SQL builder remains driver-free.