This guide will help you get started with tctx for distributed tracing in your application.
Installation
First, install tctx using your preferred package manager:
Basic Usage
tctx provides two main modules: traceparent for trace identification and tracestate for vendor-specific metadata.
Import the modules
Import the traceparent and tracestate modules from tctx: import * as traceparent from 'tctx/traceparent' ;
import * as tracestate from 'tctx/tracestate' ;
Create a trace context (Producer)
When initiating a request to another service, create a new trace context: // Create new trace headers
fetch ( '/api' , {
headers: {
traceparent: traceparent . make (),
tracestate: tracestate . make ({ key: 'value' }),
},
});
The make() function creates a new W3C-compliant traceparent with:
A unique trace ID (32 hex characters)
A unique parent ID (16 hex characters)
Default flags (sampled and random)
Parse incoming traces (Consumer)
When receiving a request with trace headers, parse them and create a child span: // Parse incoming trace headers
const parent = traceparent . parse ( request . headers . traceparent );
const state = tracestate . parse ( request . headers . tracestate );
// Add your vendor-specific data
state . set ( 'vendor' , 'value' );
// Propagate to downstream services
fetch ( '/downstream' , {
headers: {
traceparent: parent . child (),
tracestate: state ,
},
});
The child() method creates a new span with the same trace ID but a new parent ID, maintaining the trace lineage.
Convert to string
Both traceparent and tracestate objects automatically convert to strings when used in headers: const parent = traceparent . make ();
console . log ( String ( parent ));
// 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
const state = tracestate . make ({ key: 'value' });
console . log ( String ( state ));
// key=value
Complete Example
Here’s a complete example showing both producer and consumer patterns:
// Producer: Initiating a traced request
import * as traceparent from 'tctx/traceparent' ;
import * as tracestate from 'tctx/tracestate' ;
fetch ( '/api' , {
headers: {
traceparent: traceparent . make (),
tracestate: tracestate . make ({ key: 'value' }),
},
});
Understanding Traceparent
The traceparent header follows this format:
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
^ ^ ^ ^
| | | flags (2 hex)
| | parent-id (16 hex)
| trace-id (32 hex)
version (2 hex)
version : Always 00 (current W3C spec version)
trace-id : 32-character hex string uniquely identifying the trace
parent-id : 16-character hex string identifying the current span
flags : 2-character hex representing trace flags (sampling, etc.)
Working with Flags
tctx provides utilities for managing trace flags:
import { sample , unsample , is_sampled } from 'tctx/traceparent' ;
const parent = traceparent . make ();
// Check if sampled
console . log ( is_sampled ( parent )); // true (by default)
// Toggle sampling
unsample ( parent );
console . log ( is_sampled ( parent )); // false
sample ( parent );
console . log ( is_sampled ( parent )); // true
According to the W3C spec, you should call .child() before modifying flags to ensure proper trace propagation.
Working with Tracestate
Tracestate is a ring buffer of up to 32 key-value pairs:
const state = tracestate . make ();
// Set values
state . set ( 'vendor1' , 'value1' );
state . set ( 'vendor2' , 'value2' );
// Get values
console . log ( state . get ( 'vendor1' )); // 'value1'
// Update moves key to front
state . set ( 'vendor1' , 'updated' );
console . log ( String ( state )); // 'vendor1=updated,vendor2=value2'
// Automatically drops oldest when full (32 entries)
for ( let i = 0 ; i < 35 ; i ++ ) {
state . set ( `key ${ i } ` , `value ${ i } ` );
}
console . log ( state . size ); // 32
Error Handling
The parse() function returns null for invalid input:
const parent = traceparent . parse ( request . headers . traceparent );
if ( ! parent ) {
// Invalid or missing traceparent, create new one
const newParent = traceparent . make ();
}
Always validate that parse() returns a non-null value before calling methods like child() to avoid runtime errors.
Next Steps
API Reference Explore the complete API documentation
Guides See more real-world usage patterns
W3C Specification Read the official W3C Trace Context spec
GitHub Repository View the source code and contribute