> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js

> Send Node.js logs, metrics, and traces to ClickHouse Observability with the ClickStack Node.js SDK.

The ClickStack Node.js SDK builds on the upstream OpenTelemetry SDK and auto-instrumentations. It adds console capture, uncaught exception capture, and telemetry flushing during shutdown. Applications that already configure OpenTelemetry can continue using their existing SDK and [configure OTLP export](https://clickhouse.com/docs/clickstack/observability/ingesting-data/opentelemetry.md).

This guide integrates:

## Install

Use Node.js **22.15 or later**. Install the SDK in your application:

```shell theme={null}
npm install @clickhouse/clickstack-node
```

The package supports ES modules and CommonJS. npm installs its `@opentelemetry/api` peer dependency automatically. If your application imports that package directly, install `@opentelemetry/api@~1.9.1`; version 1.10 is outside this SDK's supported range.

## Configure your destination

Set the environment variables before starting your application. Use a base OTLP HTTP endpoint without `/v1/traces`, `/v1/logs`, or `/v1/metrics`; exporters append those paths.

> [tab] Fully managed
>
> [Beta offering](https://clickhouse.com/docs/reference/settings/beta-and-experimental-features.md#beta-features)
>
> Open **Team Settings → Data → Managed Telemetry** and copy the **OTLP HTTP endpoint** and **API key**. Use the exact HTTPS endpoint and port shown for your service:
>
> ```shell theme={null}
> export OTEL_EXPORTER_OTLP_ENDPOINT='https://YOUR_OTEL_ENDPOINT:4318'
> export OTEL_EXPORTER_OTLP_HEADERS='authorization=Bearer%20YOUR_INGESTION_API_KEY'
> export OTEL_EXPORTER_OTLP_PROTOCOL='http/protobuf'
> export OTEL_SERVICE_NAME='my-node-app'
> ```

> [tab] Self-managed
>
> Use your collector's OTLP HTTP endpoint and the ingestion key configured for its OTLP receiver. For collector setup, see [Ingesting with OpenTelemetry](https://clickhouse.com/docs/clickstack/observability/ingesting-data/opentelemetry.md#self-managed).
>
> ```shell theme={null}
> export OTEL_EXPORTER_OTLP_ENDPOINT='http://localhost:4318'
> export OTEL_EXPORTER_OTLP_HEADERS='authorization=YOUR_INGESTION_API_KEY'
> export OTEL_EXPORTER_OTLP_PROTOCOL='http/protobuf'
> export OTEL_SERVICE_NAME='my-node-app'
> ```
>
> This endpoint assumes the application and collector run on the same host. Replace it with an address reachable from your application when the collector runs elsewhere.

## Start your application

Preload the SDK before your application imports the libraries it instruments:

```shell theme={null}
node --import @clickhouse/clickstack-node/register server.js
```

Replace `server.js` with your application’s entry file. This command loads the SDK before your application starts and uses the environment variables configured above. It supports CommonJS and ES module applications.

You can now [verify ingestion](#verify-ingestion). The alternatives below are only needed if you want to start through an npm script or configure the SDK in code.

> [accordion] Alternative startup methods
>
> `--require` is also supported. If you use `NODE_OPTIONS`, scope it to the application command so build tools do not start their own telemetry pipelines:
>
> ```shell theme={null}
> NODE_OPTIONS='--import @clickhouse/clickstack-node/register' npm start
> ```
>
> Alternatively, create an instrumentation module and preload it. The environment variables from the previous section still configure export:
>
> ```javascript theme={null}
> // instrumentation.mjs
> import { isMainThread } from 'node:worker_threads';
> import { init } from '@clickhouse/clickstack-node';
>
> if (isMainThread) {
>   init();
> }
> ```
>
> ```shell theme={null}
> node --import ./instrumentation.mjs server.mjs
> ```
>
> The guard prevents worker threads, such as Pino transport workers, from starting additional SDK instances.
>
> Use either the package's registration entry point or your own instrumentation module. Do not initialize a second SDK in the application. Static ES module imports run before the module body, so calling `init` above static imports in the same file does not guarantee initialization order.

## Verify ingestion

Start your application, make requests to an instrumented route, and emit a console message. In ClickHouse Observability, select a recent time range and search Logs or Traces for `my-node-app`. Allow time for the metrics export interval before checking metrics.

If data is missing, check SDK diagnostics on stderr, the endpoint and authentication, and network connectivity. Ensure instrumentation loads before application dependencies. Bundled libraries cannot be automatically instrumented if the bundler inlines them; keep the SDK and instrumented dependencies external. Consult [SDK compatibility](https://github.com/ClickHouse/clickstack-node#compatibility) for TypeScript, ES module, framework, and bundler requirements.

## Configure instrumentation

Standard OpenTelemetry environment variables retain their upstream meaning, including sampling, batching, exporters, and resource attributes. For example:

```shell theme={null}
export OTEL_RESOURCE_ATTRIBUTES='deployment.environment.name=production'
```

Console output is captured by default. HTTP body capture is disabled by default; enable it only when appropriate for the data your application handles:

```shell theme={null}
export CLICKSTACK_CAPTURE_HTTP_BODY='true'
```

Captured bodies can contain personal data and credentials. SDK redaction is best effort; retain collector-side redaction where needed. See the [SDK privacy options](https://github.com/ClickHouse/clickstack-node#privacy) for header capture, body limits, and sanitization.

### Initialization options

Pass these options to `init` in your instrumentation module:

| Option | Default | Purpose |
| - | - | - |
| `endpoint` | `http://localhost:4318` | Base OTLP HTTP URL; overridden by `OTEL_EXPORTER_OTLP_ENDPOINT` |
| `serviceName` | `unknown_service:` followed by the executable name | Service name; overridden by `OTEL_SERVICE_NAME` or `service.name` in `OTEL_RESOURCE_ATTRIBUTES` |
| `environment` | Unset | Set `deployment.environment.name`; the same key in `OTEL_RESOURCE_ATTRIBUTES` takes precedence |
| `apiKey` | Unset | Authorization header value; ignored if `OTEL_EXPORTER_OTLP_HEADERS` is already nonblank, even if it contains only unrelated headers |
| `httpBodyCapture` | `false` | Capture HTTP bodies; overridden by `CLICKSTACK_CAPTURE_HTTP_BODY` |
| `instrumentations` | Upstream configuration defaults | Configuration map for `getNodeAutoInstrumentations`; explicit `enabled` values override instrumentation enable/disable environment variables |
| `additionalInstrumentations` | `[]` | Additional instrumentation instances for libraries outside the default bundle |

Unset or blank environment variables allow the corresponding option to take effect. To disable console capture, include `console` in `OTEL_NODE_DISABLED_INSTRUMENTATIONS`. See the [Node.js SDK reference](https://github.com/ClickHouse/clickstack-node#quick-start) for all defaults.

For explicit process exits or AWS Lambda handlers, see the [SDK lifecycle documentation](https://github.com/ClickHouse/clickstack-node#lifecycle).

## Using the upstream SDK

If your application already configures OpenTelemetry, or needs custom processors or behavior outside the ClickStack SDK's options, use the upstream `NodeSDK` and configure OTLP export for the destination above. Follow the [upstream SDK setup example](https://github.com/ClickHouse/clickstack-node#using-the-upstream-sdk-directly), which explains the additional loader and lifecycle configuration. Do not initialize both SDKs in the same process.

## Migrating from the HyperDX Node.js SDK

Replace `@hyperdx/node-opentelemetry` with `@clickhouse/clickstack-node` and use the new registration entry point. Replace `HYPERDX_API_KEY` with `OTEL_EXPORTER_OTLP_HEADERS`, using the authorization format for your destination above.

The new SDK does not preserve every HyperDX helper or option. Review the [SDK migration guide](https://github.com/ClickHouse/clickstack-node/blob/main/docs/migration.md) before replacing logger integrations, error handlers, custom trace attributes, or sampling settings.
