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

@pond-ts/react

v0.74.0

Published

React hooks for pond-ts: subscribe to LiveSeries and derived views with throttled snapshots

Readme

pond-ts

npm CI license: MIT docs

Highly optimised, fully typed Timeseries library for TypeScript

Schema-driven events, composable batch transforms, push-based streaming ingest, multi-entity partitioning — and, optionally, React hooks and canvas charts that read the series directly. All strict TypeScript end to end, all immutable.

pond-ts is the TypeScript-first successor to pondjs, rewritten from scratch with a focus on type safety, composability, and the live-streaming patterns that pondjs never grew.

The packages

Three packages carry most projects. The core has no dependency on the other two; add them only if you render.

| Package | What it is | Needs | | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | | pond-ts — core | TimeSeries (batch) and LiveSeries (streaming) with one operator vocabulary: aggregate, rolling, align, fill, partition, join, typed columns. Node or browser, no React. | nothing | | @pond-ts/charts — optional | Declarative React charts on a canvas data plane that consume a pond series with no adapter: line, area, band, bar, scatter, box, candlestick, heat map; cursors, selection, pan/zoom, annotations. | pond-ts, @pond-ts/react, React 18/19 | | @pond-ts/react — optional | Hooks to own a series in a component and read live views on a throttled snapshot cadence (useLiveSeries, useSnapshot, …). | pond-ts, React 18/19 |

npm install pond-ts                                   # core — enough for Node pipelines and non-React apps
npm install @pond-ts/charts @pond-ts/react pond-ts    # add the React chart stack

Two domain packages (@pond-ts/financial for markets, @pond-ts/fit for activity data) and one experimental runtime (@pond-ts/process) sit on top — see Domain packages below. All six release together under one version; keep them in step.

  • Typed schemas — declare once, every transform downstream narrows off it. event.get('cpu') returns number | undefined straight from the schema; no as casts.
  • Batch + streaming with the same vocabulary — filter, map, aggregate, rolling, diff, rate, fill, cumulative, sample, reduce all exist on both TimeSeries and LiveSeries.
  • Multi-entity by construction — partitionBy('host') routes per entity; rolling / aggregate / fill / sample over a partitioned view all become per-entity automatically.
  • Bounded-memory streaming — retention policies, eviction-aware views, and sampling decouple downstream window length from event rate at firehose loads (up to 500k events/sec on a single node.js instance.)
  • Triggers — for control of rolling emission cadences. Synchronised partitioned rolling fires across partitions on every boundary.
  • Typed column extraction — series.column('cpu') returns a schema-narrowed typed column with single-pass reductions (min/max/sum/mean/stdev/median/percentile/minMax), index downsampling (bin), and a zero-copy toFloat64Array() for canvas / WebGL draw loops — no per-event allocation on the hot path.
  • No legacy baggage

Quick start: batch

import { Sequence, TimeSeries } from 'pond-ts';

const schema = [
  { name: 'time', kind: 'time' },
  { name: 'cpu', kind: 'number' },
  { name: 'requests', kind: 'number' },
  { name: 'host', kind: 'string' },
] as const;

const cpu = TimeSeries.fromJSON({
  name: 'cpu',
  schema,
  rows: [
    ['2025-01-01T00:00:00Z', 0.31, 120, 'host1'],
    ['2025-01-01T00:01:00Z', 0.44, 135, 'host2'],
    ['2025-01-01T00:02:00Z', 0.52, 141, 'host1'],
    ['2025-01-01T00:03:00Z', 0.48, 128, 'host1'],
    ['2025-01-01T00:04:00Z', 0.63, 166, 'host3'],
  ],
});

const byMinute = cpu.aggregate(Sequence.every('1m'), {
  cpu: 'avg',
  requests: 'sum',
  host: 'last',
});

const bands = cpu.baseline('cpu', { window: '2m', sigma: 2 });
//    ^ appends rolling avg / sd / upper / lower in one pass.

const anomalies = cpu.outliers('cpu', { window: '2m', sigma: 2 });
//    ^ schema-preserving filter — same columns, just the spikes.

The full batch surface (align, rolling, smooth, groupBy, join, reduce, diff, rate, fill, dedupe, materialize, sample, partitionBy, pivotByGroup, …) follows the same shape: TimeSeries in, TimeSeries out, schema preserved.

Quick start: live (streaming)

import { LiveSeries, Sequence } from 'pond-ts';

// 1. Same schema; this is a live append buffer with retention.
const live = new LiveSeries({
  name: 'cpu',
  schema,
  retention: { maxAge: '10m' }, // keep only the last 10 minutes
});

// 2. Push as events arrive. Each push is validated against the schema.
live.push([Date.now(), 0.45, 128, 'api-1']);

// 3. Compose live views — incremental, push-driven, eviction-aware.
const recentAvg = live.rolling('5m', { cpu: 'avg' });
recentAvg.on('event', (e) => render(e.get('cpu')));

// 4. Snapshot to a TimeSeries for batch analytics at any time.
const snap = live.toTimeSeries();

The full live surface (filter, map, select, window, aggregate, rolling, reduce, diff, rate, pctChange, fill, cumulative, sample) is incremental — events flow, views emit, retention bounds memory.

Quick start: charts (React)

@pond-ts/charts reads a TimeSeries or LiveSeries directly — do the maths in pond, hand the result to a layer. Rows share one x scale, so they pan, zoom and track the cursor together.

import {
  BandChart,
  ChartContainer,
  ChartRow,
  Layers,
  LineChart,
  YAxis,
  CrosshairCursor,
} from '@pond-ts/charts';

// `bands` is the baseline() result from the batch quick start:
// cpu + avg / sd / upper / lower columns.
export function CpuChart({ width }: { width: number }) {
  return (
    <ChartContainer width={width} panZoom>
      <CrosshairCursor />
      <ChartRow height={240}>
        <YAxis id="cpu" format=".0%" />
        <Layers>
          <BandChart series={bands} lower="lower" upper="upper" axis="cpu" />
          <LineChart series={bands} column="cpu" axis="cpu" />
        </Layers>
      </ChartRow>
    </ChartContainer>
  );
}

Pass width="auto" to measure the parent instead. Live data renders through the same layers: own the series with useLiveSeries from @pond-ts/react and pass its snapshot as series.

Quick start: multi-entity

partitionBy routes events into per-key buffers. Every stateful operator downstream of partitionBy runs per-partition automatically:

const perHost = cpu
  .partitionBy('host')
  .rolling('5m', { cpu: 'avg', cpu_sd: 'stdev' });

// .collect() fans the per-partition outputs back into a flat TimeSeries
// with the partition key auto-injected as a column.
const flat = perHost.collect();

Same shape on the live side — live.partitionBy('host') returns a LivePartitionedSeries whose rolling / fill / diff / sample methods all maintain per-partition state.

Quick start: bounded-memory sampling

At firehose rates, a long rolling baseline blows the heap. sample({ stride: N }) decouples baseline length from event rate; chain it between partitionBy and rolling:

// Per-host 1-in-10 stride feeding a per-host 5m baseline.
live
  .partitionBy('host')
  .sample({ stride: 10 })
  .rolling('5m', { cpu_avg: 'avg', cpu_sd: 'stdev' });

For visualization, the snapshot side ships reservoir sampling too — single-pass Algorithm R, sorted by key, fixed point count regardless of source size:

const points = series.sample({ reservoir: { size: 500 } }).toRows();
// 500 uncorrelated points drawn uniformly from the source.

Performance

Measured against three reference points (snapshot 2026-07-30; full tables, methodology, and every losing number in the benchmark reference):

  • vs pondjs (the predecessor): faster on all 54 measurable shared operations — geometric mean 20.7×, aggregate up to 453×, median 157×, and select / rename effectively instant (O(1) column rebinds).
  • vs pandas (500k-bar workload): roughly even — ahead on ema, mean, median / percentile; behind ~1.1–1.9× on the rolling studies. A five-study strategy pass runs 1.28× slower than pandas' Cython kernels.
  • vs polars, single-threaded: ahead on composite studies (bollinger 0.53×, strategy stack 0.85×, ema 0.32× — lower is pond-ts faster), behind 4–9× on whole-column reductions (the SIMD gap; half-closed already by blocked summation) and on raw ingest, where pond-ts front-loads validation the dataframe engines defer.
  • vs polars on all 10 cores: behind ~3.5× on the strategy stack — pond-ts has no parallelism today; a measured 2.42× worker-thread path is on the roadmap ([PND-PROCPAR]).

The honest one-line version: the rewrite beat its predecessor by an order of magnitude, holds its own per-core against the native engines on the composite queries that dominate real workloads, and knows exactly where it is behind. Run locally:

npm run build && node packages/core/bench/vs-pondjs.cjs

Domain packages

Optional, domain-specific, all on plain pond series:

  • @pond-ts/financial — sixty-plus oracle-verified technical studies (SMA, EMA, RSI, MACD, Bollinger, ATR, VWAP, …) that append columns to a bar series, a fluent bars.sma({ period: 20 }).rsi({ period: 14 }) form, and a TradingCalendar so session-aligned bars, rolling windows and chart axes stop at the close.
  • @pond-ts/fit — fitness and activity analytics: typed quantities with units, canonical activity series, geo (distance, elevation, best efforts), power (NP / IF / TSS, curves), heart-rate zones, splits.
  • @pond-ts/process — experimental. Computations as data: processing graphs authored fluently or composed as JSON, resolved against a declared op vocabulary with content-addressed caching, provenance and per-node timings. The API is expected to move.

Documentation

The full guide is at https://pond-ts.org/.

  • Start here — five-minute walkthrough with batch, live, and React examples.
  • Concepts — temporal keys, sequences, windowing, partitioning, triggers, late data.
  • Transforms reference — every batch operator (queries, aggregation, alignment, rolling, smoothing, sampling, cleaning, reshape, anomaly detection).
  • Live reference — LiveSeries, live transforms, triggering.
  • How-to guides — building a dashboard, ingesting messy data.
  • API reference (auto-generated) — TypeDoc output, every public class and method.
  • CHANGELOG — what shipped in each release.

Versioning

All six packages release together under one version — keep them in step.

  • Today (0.x): a minor release may contain breaking changes; each is marked breaking in the CHANGELOG with a migration note. Patch releases never break.
  • From 1.0: semver — breaking changes only in a major release.
  • Public API: the exports of each package's entry points, mapped in API.md. Anything marked experimental (including all of @pond-ts/process) or internal is excluded.

Details: pond-ts.org/docs/reference/versioning.

For coding agents

pond is built by agents and expects to be used by them. Three things exist so an agent can go from "never heard of pond" to working code without a human in the loop:

  • AGENTS.md + API.md ship inside every npm tarball — node_modules/pond-ts/AGENTS.md is a one-read guide (which package for which task, the idioms, the mistakes agents make); API.md maps every public export to its source file. Source: docs/agents/USING_POND.md, API.md.
  • https://pond-ts.org/llms.txt — every docs page with a one-line description, plus llms-<area>.txt single-fetch dumps per package.
  • Claude Code plugin — skills for core, charts and financial, versioned with the library:
    /plugin marketplace add pond-ts/pond
    /plugin install pond-ts@pond-ts

Examples

  • pond-ts-dashboard — a working React dashboard that streams synthetic per-host CPU / request metrics, computes per-host rolling baselines, flags anomalies against ±σ bands, and renders everything as live line and bar charts (~600 lines of TypeScript). Walked through end-to-end in Building a dashboard.

Develop

The repo is an npm-workspaces monorepo with six published packages (pond-ts, @pond-ts/react, @pond-ts/charts, @pond-ts/financial, @pond-ts/fit, @pond-ts/process). Node 18+ for runtime; Node 20+ for the docs site (Docusaurus).

npm install         # one-time, hoists deps for all packages
npm run build       # build both packages
npm test            # runtime + type-level tests on both packages
npm run format      # prettier write across the repo
npm run verify      # format check + build + test (CI parity)

Each package lives under packages/<name>/ (core is pond-ts, the rest match their scoped names). Docs live in website/ — its own npm root, not a workspace.

License

MIT