Add Anomaly Detection to Time Series Charts in Your Web App

A client-side engine with six detection methods and drop-in React, Vue and Angular components

By Vincenzo Manto, founder of Datastripes · Published 19 October 2026 · Updated 19 October 2026
Every product with metrics gets the same request sooner or later: tell me when something looks wrong. Traffic drops, an order value spikes, latency creeps up. A detector is easy to start and hard to trust, because the first version flags too much, the second flags too little, and nobody remembers which threshold was chosen or why.@datastripes/anomaly is an npm package that runs detection in the browser through a WebAssembly engine and draws the result for you. This page explains the six methods it offers, how to call it, what the chart shows, and the cases where you should reach for something else.

What you install

One package covers everything. The root entry, @datastripes/anomaly, contains the detection engine, column auto-discovery, the licensing client and the types, with no UI framework dependency. The /react, /vue and /angular subpaths add components and a hook or composable, and /elements registers a <datastripes-anomaly-studio> custom element for any other stack.React, Vue and Angular are optional peer dependencies, so installing the package never pulls one in.
npm install @datastripes/anomaly

Detecting anomalies in a few lines

The core function works without any UI. Give it rows with a date and a value, choose an algorithm, and it returns the points with their flags, metrics and the license status.
import { executeAnomalyDetection } from '@datastripes/anomaly';

const result = await executeAnomalyDetection({
  data: [{ date: '2024-01-01', value: 120 }, /* ... */],
  algorithm: 'ensemble',
});

console.log(result.points, result.metrics, result.licenseStatus);

Six methods and when each one fits

The algorithm option takes one of six values. They differ mostly in what they treat as normal.
  • zscore measures how many standard deviations a point sits from the mean of the whole series. It is the simplest method and works best on steady data without a trend.
  • rolling_zscore does the same inside a moving window, so a slow trend does not make every recent point look abnormal. In the chart toolbar you can change the window size and the series re-scans live.
  • iqr flags points outside the range set by the quartiles. It does not assume the data is bell shaped.
  • mad uses the median absolute deviation, which a few extreme values barely move. It is a good choice when the history itself contains outliers.
  • stl_residual separates trend and seasonality from the series and looks for outliers in what remains. Use it when your data has a weekly or yearly rhythm, since a Monday peak is normal and should not be flagged.
  • ensemble takes a majority vote across the other five, so a point is flagged only when most methods agree.

Testing a detector on your own data

Benchmarks run on other data tell you little about yours. A better test takes about ten minutes. Pick a stretch of history where you already know what went wrong, such as an outage, a billing bug or a failed campaign, and run it through each of the six methods.Note which methods caught the known events and which flagged days you consider normal. The details panel shows what each method finds and how much they agree, so you can see at a glance whether the ensemble is doing something a single method would not. Then pick the quietest method that still catches the events you care about, because a detector that cries wolf gets ignored within a week.

What your users see

The time-series chart draws a line with a shaded band for the expected range and marks anomalous points with a dot colored by severity: yellow for low, amber for medium and red for high. A details panel shows what each method finds and how much they agree, all computed in the browser.A bar mode, set through customOptions.chart.renderMode, colors each bar the same way. It reads better for sparse daily or weekly aggregates, where a line can look like noise.
import { DatastripesAnomaly } from '@datastripes/anomaly/react';

<DatastripesAnomaly
  data={rows}
  customOptions={{ chart: { renderMode: 'bar' } }}
/>

When the data has no time axis

The methods above assume ordered data, one value per timestamp. If you have two independent metrics, such as CPU against memory, price against volume or latency against error rate, a point can look normal on each axis and still be unusual as a pair.For that case the package has a separate API: executeScatterAnomalyDetection, a useScatterAnomalyDetection hook and a DatastripesScatterChart component. It flags points by their Mahalanobis distance from the center of the cloud. That distance accounts for the correlation between the two metrics, so a point far along the natural trend is treated as normal while one that breaks the trend is flagged.
interface ScatterHyperparameters {
  threshold?: number; // Mahalanobis distance threshold, default 3
}

Where the data goes and what the trial limits

Detection runs in the browser. The only network request is the license check, which sends your API key and the domain of your app to the licensing server you configure, and none of your rows.Without a valid license the package runs in a restricted trial: the history is cut to 1,000 rows, export is disabled and a watermark is shown. Only a successful answer from the licensing server lifts those limits, and there is no locally unlocked mode.

Where it is the wrong tool

A flag tells you that a point differs from the pattern, not why. Treat it as a prompt to look and show users enough context to decide. Plain z-score on seasonal data will flag every peak, so match the method to the shape of the data.The component also works only while a page is open. If you need alerts around the clock, such as paging someone when a metric breaks, you still need a server-side job watching the stream.

Questions people ask