PluginBench
Skill
Official
Pass
Audit score 90

clickhouse-js-node-coding

clickhouse/agent-skills

Write idiomatic Node.js code against ClickHouse using the @clickhouse/client package.

What is clickhouse-js-node-coding?

This skill provides reference and best practices for building applications with the ClickHouse Node.js client (@clickhouse/client) in Node.js runtimes. Use it when configuring the client, inserting rows, selecting results, binding query parameters, managing sessions, or working with ClickHouse data types—but not for browser or Edge runtime code.

  • Configure and connect the ClickHouse Node.js client with URL, settings, and headers
  • Insert rows in JSON, JSONEachRow, or raw formats with optional column selection
  • Select and parse results using appropriate formats (JSONEachRow, JSON with metadata)
  • Bind query parameters safely using query_params to prevent SQL injection
  • Manage sessions and temporary tables for multi-statement workflows
  • Handle compression (gzip, zstd) for request/response optimization

How to install clickhouse-js-node-coding

npx skills add https://github.com/clickhouse/agent-skills --skill clickhouse-js-node-coding
Prerequisites
  • Node.js runtime (not browser or Edge runtime)
  • @clickhouse/client package installed (npm install @clickhouse/client)
  • ClickHouse server instance with network access
Claude Code
Cursor
Windsurf
Cline

How to use clickhouse-js-node-coding

  1. 1.Read the Task Index in the skill to identify your use case (configure client, insert, select, parameterize, etc.)
  2. 2.Consult the corresponding reference file (e.g., reference/client-configuration.md for setup)
  3. 3.Import from @clickhouse/client and create a client with createClient({ url })
  4. 4.Use the appropriate method: client.insert() for writes, client.query() for reads, client.command() for DDL
  5. 5.Always use query_params for user-supplied values; never interpolate them into SQL strings
  6. 6.Close the client with await client.close() when no longer needed or during graceful shutdown

Use cases

Good for
  • Building a Node.js API route that inserts user data into ClickHouse and returns aggregated results
  • Setting up async inserts with server-side batching for high-throughput logging
  • Creating a Next.js Server Action that queries ClickHouse with user-supplied filter values using parameterized queries
  • Implementing a health-check endpoint that pings ClickHouse and reports connection status
  • Writing a data pipeline that selects large result sets and streams them to a file or downstream service
Who it's for
  • Node.js backend developers
  • Next.js API route and Server Action authors
  • Full-stack engineers building ClickHouse-backed applications
  • Data engineers writing ETL or ingestion scripts

clickhouse-js-node-coding FAQ

Should I use @clickhouse/client or @clickhouse/client-web?

Use @clickhouse/client only in Node.js runtimes (including Next.js Node API routes, Server Components, and Server Actions). Use @clickhouse/client-web for browser code, Web Workers, Next.js Edge runtime, and Cloudflare Workers.

What format should I use for inserting rows?

JSONEachRow is the recommended default for typical row inserts unless you are streaming raw bytes (CSV, TSV, Parquet) or have already chosen another format. See reference/insert-formats.md for format comparison.

How do I safely bind user-supplied values in queries?

Always use query_params to bind values; never use template-literal interpolation. Template-literal interpolation is a SQL injection risk. Pass values as {name: Type} in the query_params object.

What is the difference between client.insert(), client.query(), and client.command()?

Use client.insert() to write rows, client.query() to read rows that return data (with .json(), .text(), or .stream()), and client.command() for DDL and statements that don't return rows (CREATE, DROP, ALTER, etc.).

Can I override clickhouse_settings per request?

Yes. Settings passed to createClient are defaults for every request, but you can override them per-call by passing clickhouse_settings directly to insert(), query(), or command().

Full instructions (SKILL.md)

Source of truth, from clickhouse/agent-skills.


name: clickhouse-js-node-coding description: > Write idiomatic application code with the ClickHouse Node.js client (@clickhouse/client). Use this skill whenever a user is building against the Node.js client — configuring the client, pinging, inserting rows in JSON or raw formats, selecting and parsing results, binding query parameters, managing sessions and temporary tables, working with data types or customizing JSON parsing. Do NOT use for browser/Web client code.

ClickHouse Node.js Client — Coding

Reference: https://clickhouse.com/docs/integrations/javascript

⚠️ Node.js runtime only. This skill covers the @clickhouse/client package running in a Node.js runtime exclusively — including Next.js Node runtime API routes, React Server Components, Server Actions, and standard Node.js processes. Do not apply this skill to browser client components, Web Workers, Next.js Edge runtime, Cloudflare Workers, or any usage of @clickhouse/client-web. For browser/edge environments, the correct package is @clickhouse/client-web.


How to Use This Skill

  1. Match the user's intent to a row in the Task Index below and read the corresponding reference file before writing code. After reading it, scan any Answer checklist in that reference and make sure the final answer covers each relevant item; those checklists capture details users usually need but are easy to omit in short answers.
  2. Always import from @clickhouse/client (never @clickhouse/client-web) and create a client with createClient({ url }) or rely on supported defaults when appropriate. Close it with await client.close() preferably when it's no longer needed or during graceful shutdown for global resources.
  3. Prefer JSONEachRow for typical row inserts/selects unless the user has already chosen another format or is streaming raw bytes (CSV / TSV / Parquet — see examples/node/performance/). Note on clickhouse_settings: settings passed to createClient are defaults for every request; they can be overridden per-call by passing clickhouse_settings directly to insert(), query(), or command(). Always mention this when the user configures settings at the client level.
  4. Always use query_params for user-supplied values — never template- literal-interpolate them into SQL. See reference/query-parameters.md. When answering a parameter-binding question, your response must explicitly name template-literal interpolation as a "SQL injection risk" — even when the user only asked about syntax and did not raise security. The literal phrase "SQL injection" needs to appear; this is the most common mistake from PostgreSQL/MySQL users and the security framing is part of the correct answer, not an optional aside.
  5. Pick the right method for the job:
    • client.insert() — write rows.
    • client.query() + resultSet.json() / .text() / .stream() — read rows that return data.
    • client.command() — DDL and other statements that don't return rows (CREATE, DROP, TRUNCATE, ALTER, SET in a session, etc.).
    • client.exec() — when you need the raw response stream of an arbitrary statement (rare in coding scenarios).
    • client.ping() — health check; returns { success, error? }, never throws on connection failure.
  6. Note version constraints when relevant. Examples:
    • pathname config option: client >= 1.0.0.
    • BigInt values in query_params: client >= 1.15.0.
    • TupleParam and JS Map in query_params: client >= 1.9.0.
    • Configurable json.parse / json.stringify: client >= 1.14.0.
    • Time / Time64 data types: ClickHouse server >= 25.6.
    • QBit data type: ClickHouse server >= 25.10 (GA on 26.x).
    • Dynamic / Variant / new JSON types: ClickHouse server >= 24.1 / 24.5 / 24.8 (no longer experimental since 25.3).

Task Index

Identify the user's task and read the matching reference file.

TaskTriggers / symptomsReference file
Configure / connect the clientBuilding a createClient call, URL parameters, clickhouse_settings, default format, custom HTTP headersreference/client-configuration.md
Compress requests / responsescompression, gzip vs zstd, { codec } option shape, Node version requirements, web limitationsreference/compression.md
Ping the serverHealth checks, readiness probes, "is ClickHouse up?"reference/ping.md
Choose an insert format"Which format should I use to insert?", JSON vs raw, JSONEachRow vs JSON vs JSONObjectEachRowreference/insert-formats.md
Insert into a subset of columns / different databaseinsert({ columns }), excluding columns, ephemeral columns, cross-DB insertsreference/insert-columns.md
Insert values, expressions, dates, decimalsINSERT … VALUES with SQL functions, Date/DateTime from JS, Decimal precision, INSERT … SELECT; inserting a UUID into a UInt128 column is tricky — use when the user is writing code that stores a UUID as UInt128reference/insert-values.md
Async inserts (server-side batching)async_insert=1, fire-and-forget vs wait-for-ackreference/async-insert.md
Select and parse resultsJSONEachRow reads, JSON with metadata, picking a select formatreference/select-formats.md
Parameterize queriesBinding values, special characters / escaping, "SQL injection?", {name: Type} syntaxreference/query-parameters.md
Sessions & temporary tablessession_id, CREATE TEMPORARY TABLE, per-session SET commandsreference/sessions.md
Modern data typesDynamic, Variant, JSON (object), Time, Time64, QBit (vector search)reference/data-types.md
Custom JSON parse/stringifyPlug in JSONBig / safe-stable-stringify / a BigInt-aware serializerreference/custom-json.md

Conventions used in answers

  • Always show import { createClient } from '@clickhouse/client' (Node, never Web).
  • Always await client.close() at the end of self-contained snippets; in long-running services, close on graceful shutdown.
  • For inserts, prefer format: 'JSONEachRow' and values: [...] unless the user's scenario requires otherwise.
  • For selects, prefer await (await client.query({...})).json<RowType>() for small / medium result sets; for bigger results suggest streaming.
  • When showing parameter binding, use ClickHouse's native {name: Type} syntax — never $1, ?, or :name.
  • For DDL inside a cluster or behind a load balancer, set clickhouse_settings: { wait_end_of_query: 1 } on the command() call so the server only acknowledges after the change is applied. See https://clickhouse.com/docs/en/interfaces/http/#response-buffering.

Out of scope

This skill covers day-to-day coding against @clickhouse/client (Node). The following topics are intentionally not covered here:

  • Errors, hangs, type mismatches, proxy pathname surprises, log silence, socket hang-ups, ECONNRESET → use the clickhouse-js-node-troubleshooting skill.
  • Streaming, Parquet, file streams, server-side bulk moves, progress streaming, async-insert throughput tuning — see examples/node/performance/.
  • TLS, RBAC / read-only users, deeper SQL-injection guidance — see examples/node/security/.
  • CREATE TABLE patterns, deployment-shaped connection strings, replication / sharding choices — see examples/node/schema-and-deployments/.
  • Browser, Web Worker, Next.js Edge, Cloudflare Workers — use @clickhouse/client-web and see examples/web/.

Still Stuck?