Skip to main content
A simple implementation of the W3C Trace Context specification level 2. This module provides a simple API for creating, parsing, and manipulating tracestate headers. You will probably also be relying on the traceparent module to create and parse traceparent headers. Tracestates are effectively a ring buffer of 32 key-value pairs, where the key is a string of up to 256 characters and the value is a string of up to 256 characters. The key must be unique within the tracestate. Updating the tracestate is done by calling the set() method, which will update the value of the key if it exists (and move it to the front), or prepend a new key-value pair to the front of the tracestate. If the tracestate is full, the oldest key-value pair will be removed.

Quick Start

import * as tp from 'tctx/traceparent';
import * as ts from 'tctx/tracestate';

let traceparent, tracestate, tmp;
tmp = req.headers.get('traceparent');
if (tmp) traceparent = tp.parse(tmp);

tmp = req.headers.get('tracestate');
// only parse the tracestate, if we have a valid parsed traceparent, as per spec
if (traceparent && tmp) tracestate = ts.parse(tmp);
traceparent ||= tp.make();

let headers = new Headers();
if (tracestate) headers.set('tracestate', String(tracestate));

tracestate.set('vendor', 'value');

fetch('/downstream', {
  headers: { traceparent: traceparent.child(), tracestate }
})

Functions

make(initial?)

Create a new tracestate instance.
initial
Iterable<[string, unknown]>
Optional iterable of key-value pairs to initialize the tracestate
return
Tracestate
A new Tracestate instance
let tracestate = make({ key: 'value' });
tracestate.set('key2', 'value2');

console.log(String(tracestate)); // 'key2=value2,key=value'

parse(value)

Parse a tracestate header string into a tracestate instance.
value
string
required
The tracestate header value to parse
return
Tracestate
A Tracestate instance containing the parsed key-value pairs
let tracestate = parse('key=value,key2=value2');

console.log(tracestate.get('key')); // 'value'
console.log(tracestate.get('key2')); // 'value2'

tracestate.set('key', 'new-value');

console.log(String(tracestate)); // 'key=new-value,key2=value2'

Types

Tracestate

The Tracestate type represents a W3C Trace Context tracestate header, implemented as a ring buffer using a JavaScript Map. The Tracestate class extends the native JavaScript Map class, so all standard Map methods are available (e.g., get(), has(), delete(), clear(), size).

set(key, value)

Sets a key-value pair in the tracestate. If the key already exists, it updates the value and moves it to the front. If the tracestate is full (32 entries), the oldest entry is removed.
key
string
required
The key to set. Must match the pattern: [a-z0-9][_0-9a-z-*/]{0,255} or [a-z0-9][_0-9a-z-*/]{0,240}@[a-z][_0-9a-z-*/]{0,13} for vendor-specific keys
value
unknown
required
The value to set. Must be a string of up to 256 printable ASCII characters (0x20-0x7E), excluding commas and equals signs
return
this
The Tracestate instance (for chaining)
const tracestate = make();
tracestate.set('vendor', 'value');
tracestate.set('key2', 'value2');

console.log(String(tracestate)); // 'key2=value2,vendor=value'

// Updating an existing key moves it to the front
tracestate.set('vendor', 'new-value');
console.log(String(tracestate)); // 'vendor=new-value,key2=value2'
The set() method will throw a TypeError if the key or value is invalid according to the W3C Trace Context specification.

toString()

Converts the Tracestate to its string representation for use in HTTP headers.
return
string
The formatted tracestate string with comma-separated key-value pairs (e.g., “key=value,key2=value2”)
const tracestate = make();
tracestate.set('vendor', 'value');
tracestate.set('key2', 'value2');

console.log(tracestate.toString()); // 'key2=value2,vendor=value'
console.log(String(tracestate)); // Same as toString()

Map Methods

Since Tracestate extends Map, you can use all standard Map methods:
const tracestate = parse('key=value,key2=value2');

// Get a value
tracestate.get('key'); // 'value'

// Check if a key exists
tracestate.has('key'); // true

// Delete a key
tracestate.delete('key');

// Get the size
tracestate.size; // 1

// Clear all entries
tracestate.clear();

// Iterate over entries
for (const [key, value] of tracestate) {
  console.log(`${key}=${value}`);
}

Build docs developers (and LLMs) love