npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

autotel-terminal

v5.0.0

Published

Terminal dashboard for autotel traces using react-ink

Readme

autotel-terminal

Terminal dashboard for viewing OpenTelemetry traces in real-time - Beautiful react-ink powered dashboard for live trace inspection during development.

npm version License: MIT

Overview

autotel-terminal provides a beautiful, interactive terminal dashboard for viewing OpenTelemetry traces in real-time. Perfect for development and debugging, it displays spans as they're created with live statistics, filtering, and detailed span inspection.

Features

  • Real-time span streaming - See traces as they happen
  • Interactive dashboard - Navigate spans with keyboard controls
  • Error filtering - Focus on failed operations
  • Live statistics - Span count, error rate, P95 latency
  • Span details - View attributes, trace IDs, parent relationships
  • Simple setup - Just add a streaming processor to your config

Installation

npm install autotel-terminal autotel
# or
pnpm add autotel-terminal autotel
# or
yarn add autotel-terminal autotel

Quick Start

Recommended Usage

Create a StreamingSpanProcessor and pass it to init(), then use renderTerminal() with the stream:

import { init, trace } from 'autotel';
import {
  renderTerminal,
  StreamingSpanProcessor,
  createTerminalSpanStream,
} from 'autotel-terminal';

// Create streaming processor for the terminal dashboard
const streamingProcessor = new StreamingSpanProcessor(null);

// Initialize autotel with the streaming processor
init({
  service: 'my-app',
  endpoint: 'http://localhost:4318',
  spanProcessors: [streamingProcessor],
});

// Create the stream and launch the dashboard
const terminalStream = createTerminalSpanStream(streamingProcessor);
renderTerminal({ title: 'My App Traces' }, terminalStream);

// Your traced code will now appear in the dashboard
const myFunction = trace((ctx) => async () => {
  ctx.setAttribute('example', 'value');
  // ... your code
});

await myFunction();

With Backend Export

To stream to the terminal AND export to a backend (e.g., Jaeger, OTLP collector):

import { init } from 'autotel';
import {
  StreamingSpanProcessor,
  createTerminalSpanStream,
  renderTerminal,
} from 'autotel-terminal';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

// Create exporter and base processor for your backend
const exporter = new OTLPTraceExporter({ url: 'http://localhost:4318/v1/traces' });
const batchProcessor = new BatchSpanProcessor(exporter);

// Create streaming processor that wraps your batch processor
// Spans are forwarded to both the dashboard AND the backend
const streamingProcessor = new StreamingSpanProcessor(batchProcessor);

// Initialize autotel
init({
  service: 'my-app',
  spanProcessors: [streamingProcessor],
});

// Create stream and launch dashboard
const stream = createTerminalSpanStream(streamingProcessor);
renderTerminal({ title: 'My App Traces' }, stream);

With Custom Options

renderTerminal(
  {
    title: 'My App Traces',
    showStats: true,
    maxSpans: 200,
    colors: true, // Auto-detected if TTY
  },
  stream,
);

Dashboard Controls

Once the dashboard is running, use these keyboard controls:

  • ↑/↓ - Navigate through spans
  • p - Pause/resume live updates
  • e - Toggle error-only filter
  • c - Clear all spans
  • Ctrl+C - Exit dashboard

Dashboard Features

Span List

The left panel shows recent spans with:

  • Span name (truncated to fit)
  • Duration (color-coded: green < 500ms, yellow > 500ms, red = error)
  • Trace ID (first 10 characters)
  • Selection indicator (cyan )

Span Details

The right panel shows detailed information for the selected span:

  • Name, status, duration
  • Trace ID, Span ID, Parent Span ID
  • Span kind (INTERNAL, SERVER, CLIENT, etc.)
  • Attributes (first 12 attributes)

Statistics Bar

When enabled, shows:

  • Total spans
  • Error count
  • Average duration
  • P95 latency

API Reference

renderTerminal(options?, stream?)

Render the terminal dashboard.

Parameters:

  • options - Optional dashboard configuration
  • stream - The terminal span stream (from createTerminalSpanStream)

Options:

interface TerminalOptions {
  /** Dashboard title (default: 'Autotel Trace Inspector') */
  title?: string;

  /** Show statistics bar (default: true) */
  showStats?: boolean;

  /** Maximum number of spans to display (default: 100) */
  maxSpans?: number;

  /** Enable colors (default: true if TTY) */
  colors?: boolean;
}

Example:

renderTerminal(
  {
    title: 'API Server Traces',
    showStats: true,
    maxSpans: 200,
  },
  stream,
);

StreamingSpanProcessor

A span processor that emits completed spans to subscribers. Can wrap another processor or work standalone.

import { StreamingSpanProcessor } from 'autotel-terminal';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';

// Standalone (no forwarding)
const streamingProcessor = new StreamingSpanProcessor(null);

// Or wrap an existing processor (spans forwarded to both)
const batchProcessor = new BatchSpanProcessor(exporter);
const streamingProcessor = new StreamingSpanProcessor(batchProcessor);

// Subscribe to spans directly (alternative to using createTerminalSpanStream)
const unsubscribe = streamingProcessor.subscribe((span) => {
  console.log('Span ended:', span.name);
});

// Later, unsubscribe
unsubscribe();

Constructor:

new StreamingSpanProcessor(wrappedProcessor?: SpanProcessor | null)
  • wrappedProcessor - Optional processor to wrap. If provided, spans are forwarded to it. If null, spans are only emitted to subscribers.

Methods:

  • subscribe(callback: (span: ReadableSpan) => void): () => void - Subscribe to span end events. Returns unsubscribe function.
  • forceFlush(): Promise<void> - Flush wrapped processor (if any).
  • shutdown(): Promise<void> - Shutdown processor and clear subscribers.

createTerminalSpanStream(processor)

Create a terminal-compatible stream from a StreamingSpanProcessor.

import { createTerminalSpanStream, StreamingSpanProcessor } from 'autotel-terminal';

const processor = new StreamingSpanProcessor(null);
const stream = createTerminalSpanStream(processor);

// Subscribe to span events
stream.onSpanEnd((event) => {
  console.log('Span:', event.name, event.durationMs + 'ms');
});

Returns: TerminalSpanStream with onSpanEnd(callback) method.

Event Format:

interface TerminalSpanEvent {
  name: string;
  spanId: string;
  traceId: string;
  parentSpanId?: string;
  startTime: number;
  endTime: number;
  durationMs: number;
  status: 'OK' | 'ERROR' | 'UNSET';
  kind?: string;
  attributes?: Record<string, unknown>;
}

Use Cases

Development Debugging

Perfect for debugging during development - see traces in real-time without leaving your terminal:

import { init } from 'autotel';
import {
  StreamingSpanProcessor,
  createTerminalSpanStream,
  renderTerminal,
} from 'autotel-terminal';

const streamingProcessor = new StreamingSpanProcessor(null);

init({
  service: 'dev-server',
  spanProcessors: [streamingProcessor],
});

const stream = createTerminalSpanStream(streamingProcessor);
renderTerminal({ title: 'Dev Server Traces' }, stream);

Testing

Use the streaming processor to assert on spans in tests:

import { StreamingSpanProcessor, createTerminalSpanStream } from 'autotel-terminal';
import { init } from 'autotel';

const processor = new StreamingSpanProcessor(null);
const stream = createTerminalSpanStream(processor);

init({
  service: 'test',
  spanProcessors: [processor],
});

// Collect spans
const spans: TerminalSpanEvent[] = [];
stream.onSpanEnd((span) => spans.push(span));

// Run your code
await myFunction();

// Assert on spans
expect(spans).toHaveLength(1);
expect(spans[0].name).toBe('myFunction');

Custom Dashboards

Build your own dashboard using the streaming processor:

import { StreamingSpanProcessor, createTerminalSpanStream } from 'autotel-terminal';

const processor = new StreamingSpanProcessor(null);
const stream = createTerminalSpanStream(processor);

stream.onSpanEnd((event) => {
  // Send to your custom dashboard
  myCustomDashboard.addSpan(event);
});

Integration with autotel

autotel-terminal works seamlessly with autotel. Just include the StreamingSpanProcessor in your spanProcessors array:

import { init } from 'autotel';
import {
  StreamingSpanProcessor,
  createTerminalSpanStream,
  renderTerminal,
} from 'autotel-terminal';

const streamingProcessor = new StreamingSpanProcessor(null);

init({
  service: 'my-app',
  endpoint: 'http://localhost:4318',
  spanProcessors: [streamingProcessor],
});

const stream = createTerminalSpanStream(streamingProcessor);
renderTerminal({}, stream);

Requirements

  • Node.js 22+
  • Terminal with TTY support (for colors and interactivity)
  • autotel package (peer dependency)

Bundle Size

  • Core dashboard: ~25KB minified
  • With dependencies (ink, react): ~150KB total
  • Development tool - not intended for production bundles

Limitations

  • Development only - Not designed for production use
  • TTY required - Colors and interactivity require a terminal
  • Memory - Keeps spans in memory (limited by maxSpans option)
  • Single instance - Only one dashboard can run at a time

Examples

See the autotel examples directory for complete working examples:

  • apps/example-terminal - Terminal dashboard with live trace viewing

License

MIT © Jag Reehal

Links