Add to an existing project
Reuse your ClickHouse client and introduce Quarry one query at a time.
Use Quarry 0.10.0 with your existing ClickHouse connection. If you are upgrading from 0.9.x, review the migration notes for INSERT SELECT, join settings, and the Node 22 minimum.
Install
npm install quarry@0.10.0 @clickhouse/clientUse an ESM TypeScript project. Reuse the @clickhouse/client connection your
application already owns, or create one with your existing connection options.
For Node projects, install @types/node if it is not already present. Your
TypeScript configuration should include Node types and the disposable-symbol
library used by the client. Merge these settings into your existing config:
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "ES2022",
"lib": ["ES2022", "ESNext.Disposable"],
"types": ["node"],
"strict": true
}
}A bundler-based application can retain its existing Bundler module resolution.
Describe one table and query it
The table below is an example shape. Replace its names and types with your actual schema. Plain interfaces are useful for a first query; use introspection for a larger schema.
import { } from "@clickhouse/client";
import { , type } from "quarry";
interface DB {
: {
: ;
: string;
};
}
const = ({
: ..,
: ..,
: ..,
: ..,
});
const = <DB>({ });
const = .("events")
.("user_id", "event_type")
.("event_type", "=", "signup")
.(20);
const rows = await .();rows is { user_id: string; event_type: string }[]. Selecting another column
changes that result type. A misspelled column produces a type error.
Keep your existing client lifecycle: close a shared client at application
shutdown, or call await client.close() at the end of a standalone script.
Inspect before replacing an existing query
const { query: sql, params } = query.toSQL();Compare that SQL and the returned rows with your current implementation. Introduce Quarry at one query boundary, keeping the rest of your code as it is. The comparison example shows this process for a complete analytics endpoint.
Grow the schema when you need it
Generate your DB types from ClickHouse and import them into your application.
For services using only part of a large schema, derive
Pick<DB, ...>
from the shared generated type.
For a complete local database and runnable recipes using the same version, continue with the quickstart.