by finn

Official TypeScript client for ClickHouse with zero external dependencies, supporting streaming inserts and selects on Node.js, browsers, and Cloudflare Workers.
This block provides the official ClickHouse JavaScript/TypeScript client with zero external dependencies. It ships three packages: a Node.js client built on HTTP/Stream APIs, a Web client built on Fetch/Web Streams, and a shared common library. Typical buyers are backend engineers connecting a Node.js or edge-runtime application to a ClickHouse database.
client-common/ - Shared types, base ClickHouseClient class, data formatters, error types, and parsing utilities used by both platform implementationsclient-node/ - Node.js-specific client implementation using http/https modules, connection pooling, and stream.Readable supportclient-web/ - Browser/Cloudflare Worker client implementation using Fetch and Web Streams APIs# Node.js client (server-side applications)
npm install @clickhouse/client
# Web client (browsers, Cloudflare Workers)
npm install @clickhouse/client-web
# If using only shared types/common package
npm install @clickhouse/client-common
No native modules, no pod installs, no prebuild steps required. The packages are pure TypeScript/JavaScript with zero runtime dependencies.
Drop source - Place the source/ directory anywhere in your repo (e.g., src/vendor/clickhouse-js/). If importing directly from source rather than npm, add path aliases.
TypeScript config - Ensure TypeScript 4.5+ is installed. Add paths if importing from source:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2020",
"strict": true,
"paths": {
"@clickhouse/client": ["./source/client-node/src/index.ts"],
"@clickhouse/client-web": ["./source/client-web/src/index.ts"],
"@clickhouse/client-common": ["./source/client-common/src/index.ts"]
}
}
}
Environment variables - The client reads connection details at runtime, not build time. Set these in .env or your deployment config:
CLICKHOUSE_URL=http://localhost:8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=
CLICKHOUSE_DATABASE=default
ESM/CJS - The packages publish both ESM and CJS builds. For Node.js with in , imports work as-is. For CJS projects use .
Spin up an isolated sandbox and run it server-side — no local setup.
Tetrees AI Review of this version
This TypeScript cli / script completed archive review. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
Pipeline avcp-2026-08-04.1 · SHA-256 788f06a684c5fbc4…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
Reviewed Aug 4, 2026
Push this product straight into your AI IDE, web builder or cloud IDE.
Connect Tetrees to a compatible AI IDE, list products you own, and request the verified ZIP without exposing seller upload controls.
No reviews yet.
Sign in to join the discussion
Loading discussion…
"type": "module"package.jsonrequire('@clickhouse/client')Express wiring - Create a singleton client instance at app startup and share it via module scope or dependency injection. Call client.close() in your shutdown handler.
import { ClickHouseClient } from '@clickhouse/client-common'
class ClickHouseClient<Stream> {
query(params: QueryParams): Promise<ResultSet>
insert<T>(params: InsertParams<Stream, T>): Promise<InsertResult>
exec(params: ExecParams): Promise<ExecResult<Stream>>
command(params: CommandParams): Promise<CommandResult>
ping(params?: PingParams): Promise<PingResult>
close(): Promise<void>
}
The central class for all ClickHouse interactions. Use query for SELECT statements, insert for writing rows, command for DDL (CREATE/DROP), and exec when you need raw streaming access to results.
import { ClickHouseError, parseError } from '@clickhouse/client-common'
class ClickHouseError extends Error {
code: string
message: string
}
function parseError(error: unknown): ClickHouseError
Thrown by the client whenever ClickHouse returns an error response. Use parseError to normalise caught unknowns into a typed ClickHouseError for consistent error handling across query and insert paths.
import {
type DataFormat,
SupportedJSONFormats,
SupportedRawFormats,
StreamableFormats,
} from '@clickhouse/client-common'
type DataFormat =
| JSONDataFormat
| RawDataFormat
| StreamableDataFormat
| StreamableJSONDataFormat
| SingleDocumentJSONFormat
const SupportedJSONFormats: Set<DataFormat>
const SupportedRawFormats: Set<DataFormat>
const StreamableFormats: Set<DataFormat>
Use DataFormat as the type for the format field in QueryParams. The Supported* sets let you validate or branch logic based on whether a format produces JSON, raw bytes, or a streamable response.
import { TupleParam, formatQueryParams } from '@clickhouse/client-common'
class TupleParam {
constructor(values: unknown[])
}
function formatQueryParams(key: string, value: unknown): string
Use TupleParam to pass ClickHouse tuple values as named query parameters. formatQueryParams serialises a parameter key/value pair into the wire format expected by the ClickHouse HTTP interface.
Query ClickHouse and stream rows one at a time without loading the entire result into memory. Suitable for large result sets in a Node.js backend.
import { createClient } from '@clickhouse/client'
const client = createClient({
url: process.env.CLICKHOUSE_URL ?? 'http://localhost:8123',
username: process.env.CLICKHOUSE_USER ?? 'default',
password: process.env.CLICKHOUSE_PASSWORD ?? '',
database: process.env.CLICKHOUSE_DATABASE ?? 'default',
})
async function streamRows() {
const resultSet = await client.query({
query: 'SELECT number, toString(number) AS str FROM system.numbers LIMIT 100',
format: 'JSONEachRow',
})
const stream = resultSet.stream()
for await (const rows of stream) {
for (const row of rows) {
const data = row.json<{ number: string; str: string }>()
console.log(data)
}
}
await client.close()
}
streamRows().catch(console.error)
Insert structured data into ClickHouse using the JSONEachRow format. The Node.js client accepts a plain JavaScript array directly.
import { createClient } from '@clickhouse/client'
import type { InsertParams } from '@clickhouse/client-common'
interface EventRow {
event_id: string
event_type: string
ts: number
}
const client = createClient({
url: process.env.CLICKHOUSE_URL ?? 'http://localhost:8123',
username: process.env.CLICKHOUSE_USER ?? 'default',
password: process.env.CLICKHOUSE_PASSWORD ?? '',
})
async function insertEvents(events: EventRow[]) {
const result = await client.insert<EventRow>({
table: 'events',
values: events,
format: 'JSONEachRow',
clickhouse_settings: {
async_insert: 1,
wait_for_async_insert: 0,
},
})
console.log('Insert summary:', result.summary)
}
insertEvents([
{ event_id: 'abc-1', event_type: 'click', ts: Date.now() },
{ event_id: 'abc-2', event_type: 'view', ts: Date.now() },
]).catch(console.error)
Catch and inspect typed errors from ClickHouse. Useful for surfacing query errors to API callers with meaningful HTTP status codes.
import { createClient } from '@clickhouse/client'
import { ClickHouseError, parseError } from '@clickhouse/client-common'
const client = createClient({
url: process.env.CLICKHOUSE_URL ?? 'http://localhost:8123',
})
async function runQuery(sql: string) {
try {
const rs = await client.query({ query: sql, format: 'JSON' })
return await rs.json()
} catch (err) {
const chErr = parseError(err)
if (chErr instanceof ClickHouseError) {
console.error(`ClickHouse error [${chErr.code}]: ${chErr.message}`)
// map to HTTP 400, 503, etc. based on chErr.code
}
throw chErr
}
}
runQuery('SELECT * FROM non_existent_table').catch(() => process.exit(1))
client-common/src/client.ts - Abstract ClickHouseClient class with query/insert/exec/command/ping methods and all associated param/result typesclient-common/src/config.ts - BaseClickHouseClientConfigOptions interface defining URL, auth, TLS, HTTP settings shared by all platformsclient-common/src/connection.ts - Abstract connection interface and shared connection utilitiesclient-common/src/result.ts - BaseResultSet, Row, RowOrProgress, ResultJSONType, and streaming result typesclient-common/src/data_formatter/formatter.ts - Format enum definitions and format classification sets (SupportedJSONFormats, etc.)client-common/src/data_formatter/format_query_params.ts - TupleParam class and formatQueryParams for HTTP query parameter serialisationclient-common/src/data_formatter/format_query_settings.ts - formatQuerySettings for serialising ClickHouse session settingsclient-common/src/error/error.ts - ClickHouseError class and parseError utilityclient-common/src/parse/column_types.ts - ClickHouse column type parsing helpersclient-common/src/parse/json_handling.ts - JSON parsing utilities for ClickHouse response formatsclient-common/src/logger.ts - Logger interface, ClickHouseLogLevel enum, and log param typesclient-common/src/settings.ts - ClickHouse server settings type definitionsclient-common/src/clickhouse_types.ts - Shared ClickHouse domain types (ClickHouseSummary, ResponseJSON, ProgressRow, etc.)client-node/src/client.ts - Node.js createClient factory returning a fully configured Node.js clientclient-node/src/connection/node_base_connection.ts - Base HTTP connection using Node.js http/https modulesclient-node/src/connection/socket_pool.ts - Keep-alive socket pool for connection reuseclient-node/src/result_set.ts - Node.js ResultSet wrapping stream.Readableclient-node/src/config.ts - Node.js-specific config extending base (TLS, socket timeout, custom agent)client-web/src/client.ts - Web createClient factory for Fetch-based environmentsclient-web/src/connection/web_connection.ts - Fetch-based HTTP connection implementationclient-web/src/result_set.ts - Web ResultSet wrapping ReadableStreamCLICKHOUSE_URL missing scheme - The URL must include http:// or https://; bare hostnames throw a parse error. Fix: always prefix with the scheme.fetch but @clickhouse/client (Node.js) does not use it; avoid mixing the web package on older Node. Fix: use @clickhouse/client on Node.js, @clickhouse/client-web only in browsers/edge.ResultSet.stream() holds an open HTTP connection; if you abandon it without consuming, sockets leak. Fix: always await full iteration or call resultSet.close().ClickHouseError classes, causing instanceof checks to fail. Fix: pin moduleResolution to bundler or node16 and ensure a single resolution path.async_insert without wait_for_async_insert - Enabling async_insert: 1 without also setting wait_for_async_insert: 1 means inserts may silently fail post-response. Fix: set wait_for_async_insert: 1 in production or check insert summary explicitly.tsconfig paths, Node.js runtime ignores them. Fix: use tsconfig-paths/register or compile first; prefer the published npm packages for runtime use.I have purchased the clickhouse-js source block. The source lives at `source/`
relative to this file, and a full integration guide is in `USAGE.md`.
The upstream packages are:
- @clickhouse/client (Node.js)
- @clickhouse/client-web (Browser / Cloudflare Workers)
- @clickhouse/client-common (Shared types)
My project is: <describe your project, e.g. "an Express REST API in TypeScript
that needs to query ClickHouse and return JSON to frontend clients">
Please do the following step by step:
1. Read `USAGE.md` and the relevant files under `source/` to understand the
real exports and signatures.
2. Add `@clickhouse/client` (or `@clickhouse/client-web`) to my project's
dependencies as shown in USAGE.md § Required dependencies.
3. Create a `src/db/clickhouse.ts` singleton that initialises `createClient`
using environment variables CLICKHOUSE_URL, CLICKHOUSE_USER,
CLICKHOUSE_PASSWORD, and CLICKHOUSE_DATABASE.
4. Add typed query helpers for my use case: <describe your tables/queries>.
5. Wire error handling using `ClickHouseError` and `parseError` from
`@clickhouse/client-common`.
6. Show me how to call `client.close()` on process shutdown.
Only use symbols documented in USAGE.md § Public API. Do not invent any APIs.
The upstream project is released under the Apache License 2.0. See source/LICENSE if present, or refer to the official repository.
Upstream packages: @clickhouse/client, @clickhouse/client-web, @clickhouse/client-common by ClickHouse, Inc.
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
The full install guide and integration prompts unlock after purchase.
Automation, Utilities & Developer Tools
Free