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

@elitechart/core

v0.1.1

Published

Framework-agnostic charting engine, renderer, and data layer for ChartForge.

Readme

@elitechart/core

npm version types bundle size license: MIT

Framework-agnostic charting engine for ChartForge — a Professional-grade trading chart in TypeScript. Candle / line / area / bar series with Heikin-Ashi, Renko, Kagi, Point & Figure, Range Bars, Line Break, and Elder-Impulse transforms; 30+ technical indicators; 46 drawing tools; bar replay; compare-symbol overlays; magnet snap; corporate-event markers; price alerts; trade ticket; and a full keyboard-shortcut help overlay — all on a layered Canvas 2D backend that handles 100k+ bars at 60fps.

SSR note: createChart requires a DOM. Mount it from a Next.js client component ('use client' + useEffect) or from any other on-mount lifecycle. There is no top-level window access at module scope, so importing this package from a Server Component is safe.

Install

pnpm add @elitechart/core

No required peer dependencies. @elitechart/themes is optional but recommended for built-in dark / light palettes.

Quick example

import { createChart, asPrice, asTickSize, asTimestampMs, asVolume } from '@elitechart/core';
import { darkTheme } from '@elitechart/themes';

const container = document.getElementById('chart')!;

const chart = createChart(container, {
  series: {
    symbol: {
      id: 'BTCUSDT',
      ticker: 'BTCUSDT',
      description: 'Bitcoin / Tether',
      type: 'crypto',
      tickSize: asTickSize(0.01),
      priceScale: 2,
    },
    resolution: { kind: 'minutes', value: 1 },
    bars: [
      {
        time: asTimestampMs(Date.now() - 60_000),
        open: asPrice(67_000),
        high: asPrice(67_120),
        low: asPrice(66_980),
        close: asPrice(67_080),
        volume: asVolume(12),
      },
      // …more bars
    ],
  },
  kind: 'candle',
  theme: darkTheme,
});

// Live tick (e.g. from a websocket)
chart.tickLastBar({
  /* OHLCV update for the in-progress bar */
});

// Append a completed bar
chart.appendBar({
  /* finalized bar */
});

// Always dispose on teardown
// chart.dispose();

Concepts

ChartForge separates concerns into three independent layers. Understanding the boundary makes the rest of the API predictable.

Engine (createChart)

The engine owns the ChartHandle — a long-lived object that wires together the renderer, viewport, history stack, drawings, alerts, replay state, and event bus. Mutating methods (setSeries, setKind, setTheme, addDrawing, tickLastBar, …) push imperatively into the engine and flag the affected layers for repaint. The engine never re-renders the world from scratch — repaint is layer-scoped and frame-coalesced.

Renderer

A layered Canvas 2D backend with a frame scheduler, virtualized series painter (binary-search the visible bar slice; O(log N + M) per frame), memoized indicator overlays, and rolling perf instrumentation accessible via chart.getPerfStats(). The plugin API exposes the Paint seal so third-party renderers can hook into the same scheduler without touching internals.

Datafeed

ChartForge does not bundle a transport. The engine consumes a Series synchronously today; embedders fetch bars from any backend and call chart.setSeries(...) to swap. The Datafeed interface exists as a contract for future first-party adapters and for @elitechart/elitechart's real-time wiring — see "Datafeed contract" below.

What's in the box

Series kinds

candle, line, area, bar, heikin-ashi, hollow-candle, renko, line-break, kagi, point-figure, range-bars, elder-impulse. Switch at runtime via chart.setKind(kind) — aggregations recompute lazily and the viewport stays anchored.

Drawing tools (in @elitechart/drawings)

46 tools — Trend, Ray, Extended, Horizontal, Horizontal Ray, Vertical, Parallel Channel, Arrow, Rectangle, Ellipse, Fib Retrace / Ext / Channel / Time Zone, Trend-Based Fib Time, Price Range, Date Range, Date+Price, Text, Brush, Highlighter, Path, Polyline, Triangle, Circle, Arc, Rotated Rectangle, Callout, Note, Price Label, Flag Mark, Signpost, Arrow Marker (+up/down/left/right), Long Position, Short Position, Position Forecast, Pitchfork (Andrews / Schiff / Modified Schiff / Inside), Anchored VWAP, Fixed-Range Volume Profile.

Indicators (in @elitechart/indicators)

30+ — SMA, EMA, WMA, VWMA, DEMA, TEMA, HullMA, Bollinger + %B, Keltner, Donchian, StDev, RSI, Stochastic, MACD, CCI, ROC, Williams %R, Aroon, TSI, ATR, ADX, PSAR, SuperTrend, OBV, VWAP, MFI, CMF, Pivots, Ichimoku.

UX

  • Drag / wheel pan + zoom with momentum scrolling (honors prefers-reduced-motion)
  • Pinch-zoom + touch pan + long-press context menu on mobile (44px+ touch targets)
  • Drag price-axis to rescale Y, drag time-axis to rescale X, double-click gutter to re-engage auto-fit
  • Crosshair with price + time pills, magnet-snap to OHLC or drawing endpoints (off / weak / strong)
  • OHLCV legend at top-left showing the hovered bar's values (+ compare-series rows)
  • Last-price pill at the right gutter with bull/bear coloring and a dashed connector
  • Axis "+" quick-action menu for Add alert / Draw horizontal line / Buy / Sell
  • Replay mode with drag-to-select range, play/pause, step ±1/±10 bars, Space/←/→ shortcuts
  • Marquee select (Shift+drag), arrow-key nudge (1px / 10px with Shift), full undo/redo
  • Settings dialog for candle colors / background / grid / font
  • Alerts management dialog with per-alert edit/delete
  • PNG / JPEG / WebP export via chart.exportPng()
  • Keyboard shortcut help overlay — press ? to see every binding

Performance

@elitechart/core ships under the 150KB gzipped budget with all UI components included. Drawings + indicators are separate, tree-shakeable packages. chart.getPerfStats() exposes rolling last/avg/peak ms + frame count for hot-path verification.

Plugin API

Custom indicators / overlays / drawing tools via IndicatorPlugin, OverlayPlugin, DrawingPlugin. Hot-swappable renderer backend (Canvas 2D today; WebGL pluggable through the Paint seal).

SSR & headless usage

createChart requires a DOM. From Next.js App Router:

'use client';
import { useEffect, useRef } from 'react';
import { createChart, type ChartHandle } from '@elitechart/core';
import { darkTheme } from '@elitechart/themes';

export function Chart({ series }: { series: Parameters<typeof createChart>[1]['series'] }) {
  const ref = useRef<HTMLDivElement>(null);
  const chartRef = useRef<ChartHandle | null>(null);

  useEffect(() => {
    if (ref.current === null) return;
    chartRef.current = createChart(ref.current, { series, theme: darkTheme });
    return () => chartRef.current?.dispose();
  }, [series]);

  return <div ref={ref} style={{ height: 480 }} />;
}

For a friendlier React experience, use @elitechart/react which wraps this boilerplate behind <Chart /> + useChart.

For unit tests + Web Workers, the data validation, math (LinearScale, LogScale, priceBounds, niceTicks), and series-aggregation helpers (computeHeikinAshi, computeRenkoBricks, computeKagi, computePointFigure) are all pure functions with no DOM dependency — import them directly without booting an engine.

Datafeed contract

import type { Datafeed } from '@elitechart/core';

const feed: Datafeed = {
  async getBars({ symbol, resolution, from, to, signal }) {
    const res = await fetch(`/api/bars?s=${symbol.id}&from=${from}&to=${to}`, { signal });
    return res.json();
  },
  subscribe({ symbol, resolution }, onBar) {
    const ws = new WebSocket(`wss://example.com/${symbol.id}`);
    ws.onmessage = (e) => onBar(JSON.parse(e.data));
    return () => ws.close();
  },
  searchSymbols: async (q) => fetch(`/api/search?q=${q}`).then((r) => r.json()),
  resolveSymbol: async (id) => fetch(`/api/symbol/${id}`).then((r) => r.json()),
};

Works with REST + polling, WebSocket streams, or any custom transport. @elitechart/elitechart will consume this contract first-party in a coming phase; today the engine pulls bars synchronously from Series and the embedder owns transport.

Layout persistence

const layout = chart.serializeLayout({ savedAt: Date.now() });
localStorage.setItem('my-chart', JSON.stringify(layout));

const saved = JSON.parse(localStorage.getItem('my-chart')!);
chart.loadLayout(saved, drawingToolRegistry);

Bars are NOT serialized — the embedder re-fetches them using the symbol + resolution fields on the layout.

Theming

CSS variable tokens (--cf-color-*, --cf-space-*, --cf-font-*). Runtime swap via chart.setTheme(theme) or patch tokens individually via chart.patchTheme({ seriesUp: '#26a69a' }). Dark + light themes ship in @elitechart/themes; custom themes implement the same token map.

Compatibility

  • Node 20.11+ (build / SSR import). DOM-free helpers are Node-clean.
  • Browsers Chrome / Safari / Firefox / Edge (evergreen), iOS Safari 16+, Android Chrome. Pointer Events throughout — unifies mouse / touch / pen handling.
  • TypeScript 5.0+ recommended for branded-primitive narrowing.
  • SSR safe. No window / document access at module scope; createChart runs only when called.
  • Tree-shakeable ESM + CJS dual emit, named exports only, sideEffects: false.

Links

License

MIT — see LICENSE.