NewsJavaScriptDeveloper Tools

OpenTelemetry JS SDK 3.0: What Breaks and How to Migrate

OpenTelemetry JavaScript SDK 3.0 distributed tracing network diagram showing migration breaking changes
OpenTelemetry JS SDK 3.0 ships four breaking changes — trace package consolidation, Node.js 22+ requirement, Jaeger removal, and re-export cleanup.

OpenTelemetry JavaScript SDK 3.0 shipped on October 15. It is a housekeeping release — but “housekeeping” here means four breaking changes that will silently break your Node.js apps the moment you run npm update without reading the changelog. The headlines: three trace packages are gone, Jaeger support is dropped, Node.js 18 and 20 no longer work, and re-exports you probably depended on are removed. Here is exactly what changed and the fastest path to fix it.

Check Node.js First — That’s the Hard Gate

Before touching a single dependency, run node --version. If you are on anything below v22, SDK 3.0 will not run. Node.js 22 LTS is the minimum. Node.js 18 hit end-of-life in April 2026. Node.js 20 hit EOL the same month. The OTel team has been clear about this for months, but teams in enterprise environments tend to lag. Upgrading to Node.js 22 is the non-optional first step — and it is worth doing regardless of this migration, given Node 18 has received no security patches for six months.

The Biggest Change: Three Trace Packages Became One

The most widespread breaking change is the consolidation of the trace SDK. @opentelemetry/sdk-trace-node, @opentelemetry/sdk-trace-base, and @opentelemetry/sdk-trace-web are all gone. They merged into a single @opentelemetry/sdk-trace package. Nearly every OTel-instrumented application imports at least one of these three. The good news: the unified package was available as a backport since June 2026 (v2.9.0), so you can migrate today without jumping to 3.0. Track the full migration details in GitHub issue #6926.

The import change is mechanical:

// Before
import { NodeTracerProvider } from @opentelemetry/sdk-trace-node;
import { SimpleSpanProcessor } from @opentelemetry/sdk-trace-base;

// After
import { NodeTracerProvider, SimpleSpanProcessor } from @opentelemetry/sdk-trace;

The consolidation also removes the .register() method from NodeTracerProvider and WebTracerProvider. That method never existed in the logs or metrics SDKs — it was a trace-specific convenience that created API inconsistency. The replacement is explicit:

// Before
provider.register({ propagator: new W3CTraceContextPropagator() });

// After
provider.addSpanProcessor(new BatchSpanProcessor(exporter));
api.trace.setGlobalTracerProvider(provider);
api.propagation.setGlobalPropagator(new W3CTraceContextPropagator());

More verbose, but consistent with how you initialize every other OTel SDK component.

Jaeger Support Is Gone — Switch to OTLP

Four packages are dropped outright: @opentelemetry/propagator-jaeger, @opentelemetry/exporter-jaeger, @opentelemetry/shim-opentracing, and @opentelemetry/shim-opencensus. If you are still using the Jaeger exporter, the fix is to switch to the OTLP exporter and point it at your Jaeger backend — Jaeger has accepted OTLP natively since v1.35, so you likely do not need to touch your Jaeger infrastructure at all.

// Before
import { JaegerExporter } from @opentelemetry/exporter-jaeger;
const exporter = new JaegerExporter({ endpoint: http://jaeger:14268/api/traces });

// After
import { OTLPTraceExporter } from @opentelemetry/exporter-trace-otlp-http;
const exporter = new OTLPTraceExporter({ url: http://jaeger:4318/v1/traces });

Port 4318 is Jaeger’s OTLP HTTP receiver. For gRPC, use port 4317 with @opentelemetry/exporter-trace-otlp-grpc. If you are on OpenTracing or OpenCensus shims, there is no equivalent drop-in — those legacy APIs need migration to native OpenTelemetry instrumentation. The shims existed to ease transition, not to be permanent infrastructure.

Re-exports Are Gone — Imports Need to Be Explicit

@opentelemetry/sdk-node was quietly re-exporting api, core, sdk-logs, sdk-metrics, and resources. That convenience is removed. If your codebase imported these through sdk-node, add the direct imports:

// Before (worked as an accidental re-export)
import { Resource } from @opentelemetry/sdk-node;

// After
import { Resource } from @opentelemetry/resources;

A related change: deep path imports into build output now throw ERR_PACKAGE_PATH_NOT_EXPORTED. Anything that looks like @opentelemetry/sdk-logs/build/src/Logger will fail. SDK 3.0 ships a proper exports map — use the top-level package import instead.

ESM/CJS: Mostly Transparent, One Caveat

SDK 3.0 ships proper dual ESM/CJS exports via a build migration to tsdown. Files moved from build/src/ to dist/ with .cjs/.mjs extensions. For most teams, bundlers that respect package.json exports handle this automatically. The only teams affected are those with custom webpack or rollup configurations that hardcoded paths into OTel package internals — those paths no longer exist. The upside: ESM applications no longer lose spans due to missing loader hooks, which was a real pain in SDK 2.x.

Your Migration Checklist

Run these five checks before upgrading. Most can be done with a codebase search:

  1. Node.js version: node --version must return v22 or higher
  2. Trace package imports: Search for sdk-trace-node, sdk-trace-base, sdk-trace-web — replace all with sdk-trace
  3. Jaeger packages: Search for propagator-jaeger, exporter-jaeger — switch to OTLP exporter
  4. Legacy shims: Search for shim-opentracing, shim-opencensus — these require native OTel migration, no replacement shim exists
  5. sdk-node re-exports: Search imports from @opentelemetry/sdk-node for symbols like Resource, metrics, logs — add direct package imports

Should You Upgrade Now?

If you are on Node.js 22 and not using Jaeger or the legacy shims, the migration is a few import path changes — probably an hour of work for most codebases. The sdk-trace unified package has been available since June so you can stage the trace migration separately from the 3.0 upgrade.

If you are on Node.js 18 or 20, fix that first. Running a six-month-old EOL runtime to avoid an upgrade is not a maintenance strategy. The 2.x branch is in feature-freeze since September 1 — critical security fixes only. The migration cost is low for most teams. The cost of sitting on an EOL runtime and a security-frozen SDK compounds quietly until it does not.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:News