o11ykit

foundation layer

OTLP in. Charts out.

Four packages that parse OTLP JSON, filter and group records, build library-agnostic frames, and project them into Chart.js, ECharts, Recharts, or uPlot configs. Zero backend required.

The Pipeline

@otlpkit/otlpjson
Parse OTLP JSON, detect signals, normalize timestamps, flatten attributes
@otlpkit/query
Filter, group, bucket time-series, select latest values
@otlpkit/views
Build frames: time-series, latest values, histograms, trace waterfalls
@otlpkit/adapters
Project to Chart.js, ECharts, Recharts, or uPlot native configs

Packages

@otlpkit/otlpjson
Parse raw OTLP JSON documents. Signal detection (metrics, traces, logs), timestamp normalization, attribute flattening, typed iterators.
  • parseOtlpJson()
  • collectMetricPoints()
  • collectSpans()
  • collectLogRecords()
@otlpkit/query
Materialize signals into queryable record sets. Filter by attributes, group by labels, bucket into time windows with sum/avg/min/max/count/rate.
  • filterRecords()
  • groupBy()
  • bucketTimeSeries()
  • selectLatestValues()
@otlpkit/views
Build reusable, library-agnostic frame objects. Incremental ingest store with bounded memory. Frame merging and append operations for streaming updates.
  • buildTimeSeriesFrame()
  • buildLatestValuesFrame()
  • createTelemetryStore()
  • appendTimeSeriesFrame()
@otlpkit/adapters
Minimal translation layer to each chart library's native idioms. Row-based for Recharts, dataset/encode for ECharts, columnar for uPlot.
  • toChartJsLineConfig()
  • toEChartsTimeSeriesOption()
  • toRechartsLineData()
  • toUPlotTimeSeriesModel()

Integration Example

Fetch OTLP from your API, build a frame, render a chart — three imports, five lines of glue.

import { buildTimeSeriesFrame, buildLatestValuesFrame } from "@otlpkit/views";
import { toEChartsTimeSeriesOption } from "@otlpkit/adapters/echarts";

const metricsDoc = await fetch("/api/telemetry/metrics").then((r) => r.json());

const latency = buildTimeSeriesFrame(metricsDoc, {
  signal: "metrics",
  metricName: "http.server.duration",
  splitBy: "resource.service.name",
  intervalMs: 10_000,
  title: "P95 latency by service",
});

const option = toEChartsTimeSeriesOption(latency);

Works With

Chart.js ECharts Recharts uPlot Visx