with one click
opentelemetry-js-propagation
// Context propagation for OpenTelemetry JavaScript — automatic via instrumentation libraries and manual inject/extract for custom protocols.
// Context propagation for OpenTelemetry JavaScript — automatic via instrumentation libraries and manual inject/extract for custom protocols.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | opentelemetry-js-propagation |
| description | Context propagation for OpenTelemetry JavaScript — automatic via instrumentation libraries and manual inject/extract for custom protocols. |
| tech_stack | ["opentelemetry"] |
| language | ["javascript","typescript"] |
| capability | ["observability"] |
| version | OpenTelemetry JS unversioned |
| collected_at | "2025-10-13T00:00:00.000Z" |
Source: https://opentelemetry.io/docs/languages/js/propagation/
Correlate traces across distributed services regardless of process/network boundaries. Propagation ensures spans from different services share the same traceId and maintain correct parent-child relationships. Uses the W3C Trace Context standard (traceparent/tracestate), which is language-agnostic — correlation works across services written in any OpenTelemetry-supported language.
@opentelemetry/api (never the SDK) so they remain compatible with any OpenTelemetry setup.Instrumentation libraries handle propagation transparently. Example with undici:
import { NodeSDK } from '@opentelemetry/sdk-node';
import { SimpleSpanProcessor, ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node';
import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici';
const sdk = new NodeSDK({
spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())],
instrumentations: [new UndiciInstrumentation()],
});
sdk.start();
// Outbound requests automatically carry traceparent/tracestate headers
import { request } from 'undici';
request('http://localhost:8080/rolldice').then(r => r.body.json().then(console.log));
The receiving service (also instrumented) will see parentSpanContext populated with isRemote: true, the client's spanId as parent, and the shared traceId.
Supported auto-propagation libraries include: @opentelemetry/instrumentation-http, @opentelemetry/instrumentation-undici, @opentelemetry/instrumentation-express, and others.
Use when no instrumentation library covers your transport. Two operations:
import { context, propagation } from '@opentelemetry/api';
const carrier = {};
propagation.inject(context.active(), carrier);
// carrier now has { traceparent: '00-...', tracestate: '...' }
// Send carrier fields via your transport
import { context, propagation, trace } from '@opentelemetry/api';
const carrier = { traceparent: '00-...', tracestate: '...' }; // from transport
const extractedCtx = propagation.extract(context.active(), carrier);
const tracer = trace.getTracer('my-service');
const span = tracer.startSpan('handle-request', { attributes: {} }, extractedCtx);
trace.setSpan(extractedCtx, span); // make it active
// ... do work ...
span.end();
Any spans created with extractedCtx as parent will belong to the same trace.
propagation.inject(ctx, carrier) — Serializes traceparent and tracestate from the context into a carrier object (mutated in place). The carrier can be any object.propagation.extract(ctx, carrier) — Deserializes context from a carrier, returns a new Context with the extracted span context.context.active() — Returns the currently active context (the one on the current async execution).trace.setSpan(ctx, span) — Associates a span with a context, making it the active span.tracer.startSpan(name, opts, ctx) — Creates a span with ctx as parent context.@opentelemetry/api work whether or not OpenTelemetry is wired up.@opentelemetry/api, never on SDK packages. The SDK is an application-level concern.node --import ./instrumentation.mjs rather than --require.propagation.inject mutates the carrier in place — it does not return a new object.traceparent headers.traceparent/tracestate in your wire format (JSON fields, message headers, etc.) and extract them on the receiving side.{ _meta: { traceparent, tracestate } } in your JSON payload, extract it on the server, and create child spans from the extracted context.