opentelemetry-js: the JavaScript SDK for traces, metrics and logs
OpenTelemetry JavaScript Client
At a glance
- What is it?
- opentelemetry-js is the JavaScript implementation of OpenTelemetry, split into a vendor-neutral API and a configurable SDK. It fits Node services that want instrumentation they can point at any backend, and it is heavier than most teams expect.
- Who is it for?
- Adopt opentelemetry-js if you want traces, metrics and logs recorded through one vendor-neutral API and you accept the API/SDK split and the experimental package boundary. Do not adopt it if you need a single dependency that instruments your framework for you, or if you cannot pin compatible versions across the core and contrib packages.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What opentelemetry-js solves, and who ends up using it
The README describes the project plainly: it is "the JavaScript version of OpenTelemetry, a framework for collecting traces, metrics, and logs from applications." The problem it addresses is instrumentation lock-in. If you wire your code directly to a tracing vendor's library, changing backends means rewriting call sites. opentelemetry-js separates the call sites from the exporter, so application code talks to an API while the SDK decides where the data goes. That split is the whole design, and it is why the repository publishes an api/ directory alongside packages/ and experimental/.
The audience is narrower than the topic list suggests. This is for teams running Node.js services who have someone willing to own telemetry configuration as a piece of infrastructure. A small script that logs to stdout does not need it. A service that already has a vendor agent installed and working does not gain much from swapping it out. The case for opentelemetry-js is strongest when several services written by different teams need to report into one collector, and when the backend choice is expected to change.
The repository is a monorepo. Beyond api/ and packages/, the top level carries semantic-conventions/, experimental/, integration-tests/, e2e-tests/, bundler-tests/ and examples/. That layout tells you something about scope: the project ships the specification-driven pieces and the tests that keep them aligned, not a finished product with a single entry point.
The API and SDK split, and how telemetry actually leaves your process
Two layers are in play. The API is what your code imports to create spans, metrics and log records. The SDK is what you configure at startup to decide sampling, resource attributes and export. Until the SDK is registered, API calls are effectively inert, which is why the quick start calls sdk.start() before the application does any work.
Data flow is straightforward once you see it. Instrumentation hooks into a library (HTTP, a database driver, a framework) and produces spans. Those spans carry a resource describing the process, which the README populates through resourceFromAttributes with ATTR_SERVICE_NAME set to a service name. A trace exporter then ships the finished spans somewhere, and the README's example uses ConsoleSpanExporter, which prints them rather than sending them over a network. In production you would swap that exporter for an OTLP one and point it at a collector.
The README is explicit that most of the project's documentation assumes the compiled application runs as CommonJS, and it links doc/esm-support.md for the ECMAScript Modules case. That is a real architectural constraint, not a footnote. If your build emits ESM, the startup ordering and the require calls in the example will not apply unchanged, and you need to read that document before copying anything.
Installing opentelemetry-js and getting a first trace out
The README's quick start installs three packages. Dependencies tagged latest on NPM are stated to be compatible with each other, and the README points at a version compatibility matrix for the rest.
npm install --save @opentelemetry/api
npm install --save @opentelemetry/sdk-node
npm install --save @opentelemetry/auto-instrumentations-nodeThe third package is described in the README as a meta package from opentelemetry-js-contrib that initializes multiple Node.js instrumentations at once. It is not part of this repository, which matters when you are tracing where a behaviour comes from.
Next, create a file that builds the SDK before your application loads. The README's example registers a service name, a console exporter and the auto-instrumentations, then starts the SDK.
// tracing.js
'use strict'
const process = require('process');
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace');
const { resourceFromAttributes } = require('@opentelemetry/resources');
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
const traceExporter = new ConsoleSpanExporter();
const sdk = new opentelemetry.NodeSDK({
resource: resourceFromAttributes({
[ATTR_SERVICE_NAME]: 'my-service',
}),
traceExporter,
instrumentations: [getNodeAutoInstrumentations()]
});
sdk.start();The README also shows a SIGTERM handler that calls sdk.shutdown() and exits, which is the part people skip and then wonder why the last spans never appear.
Run the application with the tracing file preloaded:
node -r ./tracing.js app.jsWith the console exporter in place, the README states that the example emits auto-instrumented telemetry about your Node.js application to the console. Spans printed to the terminal mean the wiring works; from there, replacing ConsoleSpanExporter with an OTLP exporter is the change that sends data to a collector.
Where opentelemetry-js gets awkward: beta status, versioning and the empty exporter
The repository README carries a beta status badge. That is the project's own label, and it should shape how you plan upgrades. A beta SDK means the API surface you build against can move, and the release list shows why: the core line is at v2.11.0 while a parallel experimental line is at v0.222.0. Two version sequences with different numbers is a signal that some packages have not reached the same stability level as others.
The practical failure mode follows from that. The README says dependencies tagged latest on NPM should be compatible with each other, which implies that mixing versions is where things break. A team that pins @opentelemetry/sdk-node from one release and pulls @opentelemetry/resources transitively from another can end up with a resource that never attaches, or an exporter that silently receives nothing. The README's answer is the version compatibility matrix, and it is the first thing to check when telemetry disappears after an unrelated dependency bump.
The second failure mode is the one the README's own debugging section anticipates: an application instrumented as outlined may not behave as expected, for instance when it is meant to send data to an OpenTelemetry collector. The example uses a console exporter, so it proves the SDK started, not that anything reached a collector. Those are different problems, and the console output will look perfectly healthy in both cases.
Finally, auto-instrumentations-node lives in opentelemetry-js-contrib, not here. If an instrumentation misbehaves, the issue belongs to a different repository with a different release cadence, and the compatibility promise in this README does not cover it.
How opentelemetry-js differs from a vendor agent or a hosted APM SDK
The obvious alternative is a vendor's own Node.js agent, the kind installed as a single package that patches common libraries and ships data straight to that vendor's backend. The difference is where configuration lives. A vendor agent decides the protocol, the sampling defaults and the backend for you, and it usually works after one install command. opentelemetry-js gives you the API as a separate package from the SDK, so you choose the exporter, the resource attributes and the sampler yourself, and you can change backend by changing the exporter rather than the call sites.
That trade is real in both directions. The vendor agent will be faster to a first dashboard. opentelemetry-js will be slower to that first dashboard and considerably easier to move later, provided you keep the API and SDK versions aligned. If you never expect to change backends and your vendor's agent covers your stack, the agent is the smaller commitment.
A second comparison is instrumentation coverage. Auto-instrumentation in the OpenTelemetry ecosystem is split across this repository and opentelemetry-js-contrib, so coverage for a given framework may arrive in contrib first. A vendor agent that targets your framework explicitly may cover it sooner. The counterargument is that the OpenTelemetry instrumentation is shared across backends, so a fix lands once for everyone rather than in one vendor's agent.
Maintenance, licence and the cost of keeping up
The repository is not archived, and the last push was on 2026-09-23. Recent releases include v2.11.0 and experimental/v0.222.0, both dated 2026-08-31, with v2.10.0 on 2026-07-21. The cadence is regular, but the experimental line's version number tells you not to treat every package as equally settled.
Upgrade cost is mostly bookkeeping. The repository is a Lerna and Nx monorepo, and its root package.json wires compile, test, lint and docs through nx run-many targets, with a version:update script for bumping package versions. That tooling matters to contributors, not to consumers, but it explains why releases land as coordinated sets rather than one package at a time. As a consumer your job is to move the @opentelemetry packages together and re-read the compatibility matrix rather than upgrading one of them in isolation.
The licence is Apache-2.0, and the README links to the LICENSE file at the repository root. Apache-2.0 is a permissive licence that includes an explicit patent grant, which is generally why infrastructure projects choose it. It also carries notice and attribution obligations, so if you redistribute the packages or bundle them into a product, the notices travel with them. That is a description of the licence text, not legal advice; a lawyer should review redistribution.
The cost the README does not quantify is the operator's time. Someone has to decide what the resource attributes say, which exporter is configured per environment, and what happens when the collector is unreachable. The SDK will start either way, and the console exporter example will look fine while nothing is being exported.
Editorial conclusion
Adopt opentelemetry-js if you want traces, metrics and logs recorded through one vendor-neutral API and you accept the API/SDK split and the experimental package boundary. Do not adopt it if you need a single dependency that instruments your framework for you, or if you cannot pin compatible versions across the core and contrib packages. Before rolling it out, check the version compatibility matrix in the README against the exact @opentelemetry packages you install, and confirm the ESM versus CommonJS guidance in doc/esm-support.md matches how your application is built.
Frequently asked questions
What is OpenTelemetry used for?
The README describes OpenTelemetry as a framework for collecting traces, metrics, and logs from applications, and opentelemetry-js as its JavaScript version. In practice you use it to instrument an application once and then export that telemetry to whichever backend or collector you configure.
Is OpenTelemetry free or paid?
The repository is licensed under Apache-2.0, and the README links to the LICENSE file at the root. The packages install from NPM, so there is no licence fee for the SDK itself, though whatever backend or collector you export to may have its own terms.
Is OpenTelemetry difficult to learn?
The README's quick start is short, but it notes that much of the documentation assumes the compiled application runs as CommonJS and links doc/esm-support.md for the ESM case. The API and SDK are separate packages, so the initial setup involves more moving parts than a single-package agent.
What is the difference between telemetry and OpenTelemetry?
Telemetry is the traces, metrics and logs an application produces. OpenTelemetry is a framework for collecting those signals, and opentelemetry-js is the JavaScript implementation of that framework.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/open-telemetry-opentelemetry-js)