Skip to content

Find a component

Loading the directory…

↑ ↓ to select · Enter to open · Esc to closeBrowse all →
Contributor login

Clickhouse

Buffered analytical event export

Bijection source
git clone https://github.com/bijectionhq/clickhouse.git
cd clickhouse
git checkout 24cf4910fe82aed34d05e7154fe9d3075a9650e4

Bijection repository access is required. Request access.

Description

Buffered analytical event export

Explore the package README for API concepts, configuration, and examples. Check the Bijection source for adaptation-specific setup.

Available to evaluate

Review the source and its dependencies before adopting this package. Source availability does not establish npm publication or runtime qualification.

Getting started

  1. Get the source at the revision above and read its package documentation.
  2. Check the required Bijection SDK version, dependencies, and external service credentials.
  3. Follow the package setup instructions and the guide to using components.
  4. Exercise the component in your deployment according to your project’s verification rules.

Open source

Maintained source: bijectionhq/clickhouse. Based on robertalv/clickhouse. License: MIT. Consult the repository for license terms, notices, and contributor attribution.

From the upstream publisher

Convex component for integrating with ClickHouse Cloud analytics

Explore the demo ↗

Upstream overview

From the upstream package documentation.

This component buffers analytics events in Convex's database and flushes them in batches to ClickHouse Cloud via the ClickHouse HTTP API. It decouples high-frequency write operations from synchronous external HTTP calls by staging rows locally and draining them through a separate action, typically triggered by a cron or scheduler. Configurable batch size, retry logic, and a read-only query interface round out the integration surface.

Use cases

From the upstream package documentation.

  • Tracking user or workspace events from mutations without blocking on an external HTTP call to ClickHouse
  • Running scheduled batch exports of buffered analytics rows to ClickHouse Cloud on a cron interval
  • Querying ClickHouse for read-only analytics results (SELECT, WITH, SHOW, DESCRIBE) from within Convex actions
  • Building a product analytics pipeline where Convex handles ingestion and ClickHouse handles aggregation and querying
  • Testing ClickHouse integration logic locally using the provided convex-test helper without a live ClickHouse instance

How it works

From the upstream package documentation.

Mount the component in convex/convex.config.ts using app.use(clickhouse), then instantiate a ClickHouse client in a local wrapper file. The constructor accepts your ClickHouse Cloud credentials (url, user, password) pulled from environment variables, along with options for batchSize and maxRetries.

The insert(ctx, tableName, rows) method is called from mutations to buffer rows into Convex's database. Table names are validated and quoted before use, accepting formats like events or analytics.events. No external HTTP call happens at insert time, keeping mutations fast and transactionally safe.

The flush(ctx) method is called from an action to drain buffered rows to ClickHouse over HTTP. It returns a result object with flushed, failed, and errors fields. This action is typically scheduled via a Convex cron job rather than called inline from user-facing requests.

A query<T>(ctx, sql) method is also available from actions for running read-only ClickHouse queries. It enforces a whitelist of allowed statement prefixes (SELECT, WITH, SHOW, DESCRIBE, DESC, EXPLAIN). A test helper exported from @devwithbobby/clickhouse/test integrates with convex-test for local testing without a live ClickHouse connection.

Upstream package FAQ

How do I install and mount the ClickHouse Convex component?

Run npm install @devwithbobby/clickhouse, then mount the component in convex/convex.config.ts by importing clickhouse from @devwithbobby/clickhouse/convex.config.js and calling app.use(clickhouse). After mounting, create a wrapper file in your convex directory that initializes a ClickHouse instance with your credentials, batch size, and retry settings.

Where should I store ClickHouse credentials when using this component?

The @devwithbobby/clickhouse component expects credentials to be provided via a function that reads from Convex environment variables, such as process.env.CLICKHOUSE_URL, process.env.CLICKHOUSE_USER, and process.env.CLICKHOUSE_PASSWORD. This keeps credentials out of client-side code and version control.

Why does flushing happen in a Convex action instead of a mutation?

Convex mutations cannot make outbound HTTP requests. The @devwithbobby/clickhouse component separates concerns by buffering rows during mutations and performing the actual HTTP POST to ClickHouse Cloud inside a Convex action, which supports calling external APIs. The flush action is typically scheduled via a Convex cron or scheduler.

What table name formats does the ClickHouse component accept?

The @devwithbobby/clickhouse component validates and quotes table names before inserting. Valid formats include simple names like events or database-qualified names like analytics.events. Names that do not match the expected pattern are rejected before any HTTP call is made.

Does the component support retries when ClickHouse inserts fail?

Yes. The @devwithbobby/clickhouse component accepts a maxRetries option at initialization that controls how many times a flush will retry failed batches before giving up. The flush action returns a result object with flushed count, failed count, and an array of error strings for observability.

Use with agents and CLI

Give your coding agent the component’s source identity and setup guidance.

agent-prompt.md
Help me integrate Clickhouse with Bijection.

Read: https://bijection.com/components/clickhouse/SKILL.md

Check SDK compatibility and dependency availability.
Follow this project's execution and verification rules.

Upstream README.md

View repository ↗

Documentation from robertalv/clickhouse, recorded October 23, 2026. APIs and setup may differ in the Bijection adaptation.

@devwithbobby/clickhouse

Convex component for buffering analytics events in Convex and flushing them to ClickHouse Cloud over the ClickHouse HTTP API.

Demo

Live demo: https://robertalv.github.io/clickhouse/

The demo is a static example site. It does not collect credentials or connect to a shared ClickHouse account. Users bring their own Convex deployment and ClickHouse HTTP credentials.

Run it locally:

npm install
npm run demo:dev

Install

npm install @devwithbobby/clickhouse

Mount the component in convex/convex.config.ts:

import { defineApp } from "convex/server";
import clickhouse from "@devwithbobby/clickhouse/convex.config.js";

const app = defineApp();
app.use(clickhouse);

export default app;

Use

Create a small app-local wrapper so credentials stay in your application environment:

// convex/clickhouse.ts
import { ClickHouse } from "@devwithbobby/clickhouse";
import { components } from "./_generated/api";

export const clickhouse = new ClickHouse(components.clickhouse, {
  credentials: () => ({
    url: process.env.CLICKHOUSE_URL!,
    user: process.env.CLICKHOUSE_USER!,
    password: process.env.CLICKHOUSE_PASSWORD!,
  }),
  batchSize: 500,
  maxRetries: 5,
});

Buffer rows from a mutation:

import { v } from "convex/values";
import { mutation } from "./_generated/server";
import { clickhouse } from "./clickhouse";

export const trackEvent = mutation({
  args: {
    workspaceId: v.string(),
    event: v.string(),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    await clickhouse.insert(ctx, "events", [
      {
        workspace_id: args.workspaceId,
        event: args.event,
        created_at: Date.now(),
      },
    ]);
    return null;
  },
});

Flush from an action, usually called by a cron or scheduler:

import { v } from "convex/values";
import { action } from "./_generated/server";
import { clickhouse } from "./clickhouse";

export const flushClickHouse = action({
  args: {},
  returns: v.object({
    flushed: v.number(),
    failed: v.number(),
    errors: v.array(v.string()),
  }),
  handler: async (ctx) => {
    return await clickhouse.flush(ctx);
  },
});

Run read-only analytics queries from actions:

const rows = await clickhouse.query<{ count: number }>(
  ctx,
  "SELECT count() AS count FROM events",
);

Table Names and Queries

Table names are validated and quoted before ClickHouse inserts. Valid table names look like events or analytics.events.

query() only accepts read-style statements beginning with SELECT, WITH, SHOW, DESCRIBE, DESC, or EXPLAIN.

Component Testing

This package exports a test helper for convex-test:

import { convexTest } from "convex-test";
import clickhouseTest from "@devwithbobby/clickhouse/test";

const t = convexTest();
clickhouseTest.register(t);

Publishing Checklist

Before publishing:

npm install
npm run codegen
npm run check-types
npm run build
npm test
npm pack --dry-run

Then publish:

npm publish --access public

Keywords