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

@sixtyfold/stock

v1.0.0

Published

High-performance Canvas2D OHLCV, candlestick, and market analytics charts.

Downloads

484

Readme

@sixtyfold/stock

Canvas2D OHLCV and candlestick charts with indicators, price lines, event markers, volume profiles, and continuous or compressed market-time scales.

pnpm add @sixtyfold/stock

Million-candle quickstart

Range buttons are ordinary application UI. For example:

<nav aria-label="Chart range">
  <button type="button" data-stock-range="1D">1D</button>
  <button type="button" data-stock-range="1M">1M</button>
  <button type="button" data-stock-range="6M">6M</button>
  <button type="button" data-stock-range="ALL">All</button>
  <button type="button" data-stock-days="14">14 days</button>
</nav>
<canvas id="market-chart" aria-label="Synthetic million-candle market history"></canvas>
import { StockChart, type TimeRange } from "@sixtyfold/stock";

const MINUTE = 60_000;
const DAY = 86_400_000;

function createMarketData(count = 1_000_000) {
  const timestamp = new Float64Array(count);
  const open = new Float64Array(count);
  const high = new Float64Array(count);
  const low = new Float64Array(count);
  const close = new Float64Array(count);
  const volume = new Float64Array(count);
  const start = Date.UTC(2024, 0, 1);
  let previous = 420;

  for (let index = 0; index < count; index++) {
    const target = 420 + Math.sin(index / 80_000) * 34 + Math.sin(index / 17_000) * 16;
    const movement =
      (target - previous) * 0.002 + Math.sin(index * 0.73) * 0.42 + Math.sin(index * 0.017) * 0.18;
    const next = Math.max(20, previous + movement);
    const spread = 0.25 + Math.abs(Math.sin(index * 0.13)) * 0.9;

    timestamp[index] = start + index * MINUTE;
    open[index] = previous;
    close[index] = next;
    high[index] = Math.max(previous, next) + spread;
    low[index] = Math.min(previous, next) - spread;
    volume[index] = 2_400 + Math.abs(movement) * 7_500 + (index % 1_440) * 0.8;
    previous = next;
  }

  return { timestamp, open, high, low, close, volume, length: count };
}

const data = createMarketData();
const latestTimestamp = data.timestamp[data.length - 1];
const chart = new StockChart(document.querySelector<HTMLCanvasElement>("#market-chart")!, {
  timeScale: "market",
  showVolume: true,
  candleColors: { up: "#26a69a", down: "#ef5350" },
});

await chart.initialize();
chart.setData(data);
chart.setTimeRange("6M");

const ranges: Record<string, TimeRange> = {
  "[data-stock-range='1D']": "1D",
  "[data-stock-range='1M']": "1M",
  "[data-stock-range='6M']": "6M",
  "[data-stock-range='ALL']": "ALL",
};

for (const [selector, range] of Object.entries(ranges)) {
  document.querySelector(selector)?.addEventListener("click", () => {
    chart.setTimeRange(range);
  });
}

document.querySelector("[data-stock-days='14']")?.addEventListener("click", () => {
  chart.setViewport({
    xMin: latestTimestamp - 14 * DAY,
    xMax: latestTimestamp,
  });
});

// Release the worker, observers, and event handlers when the view unmounts.
// chart.destroy();

This installs one million candles across six typed-array columns—six million generated OHLCV values. Worker rendering transfers the supplied buffers, which is why the example captures latestTimestamp before calling setData().

StockChart never inserts buttons or other controls around the supplied canvas. Build any labels and control set in your application, call setTimeRange() for the exported calendar/session presets, or call setViewport() with timestamps for an arbitrary range. Omit application controls entirely when direct wheel, pointer, touch, and keyboard navigation is enough.

Provide a localized canvas name and an adjacent summary or table for production charts. Keyboard semantics and framework-specific attributes are documented in the accessibility integration guide.

Pure OHLCV utilities, analytics, and market-layer types are exported from @sixtyfold/stock/ohlcv, /analytics, and /market-layers.

For live dashboards that must not rescale as new extrema arrive, construct the chart with yDomain: { min, max }. Either edge may be omitted to keep that side auto-scaled; omitting yDomain preserves the default visible-candle auto-scaling.

Estimated volume profiles

The optional visible-range volume profile is derived from OHLCV candles. It distributes each candle's volume uniformly across the candle's reported low-to-high range, separates bullish and bearish volume, highlights the point-of-control row, and derives the configured value area from adjacent price rows. Wider horizontal bars represent more estimated volume around that price.

OHLCV candles do not contain individual trades-at-price, so this layer is an approximation rather than exact order-flow data. Long visible ranges use a bounded aggregated source; zoomed-in ranges use raw candles.

For version-aware coding-agent guidance, connect the optional local @sixtyfold/mcp server. It is installed separately and never enters the chart runtime or browser bundle.

Third-party notices

Notices for generated runtime helper portions are in THIRD_PARTY_NOTICES.md.

Licensing

This package is source-available under the PolyForm Noncommercial License 1.0.0.

For current licensing, commercial terms, and prices, see Licensing and Commercial Terms and Pricing.