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

tickwick

v1.1.0

Published

Framework-agnostic stock charting library with candlesticks, technical indicators, and LLM-friendly declarative API

Readme

License: MIT npm

Website · Documentation · Live demo · Playground · Features · Pricing · npm · GitHub

Framework-agnostic charting for financial OHLCV data. The UI is built with Svelte 4 and D3; you embed it from React, Vue, Svelte or vanilla JavaScript without adopting Svelte in your own app. MIT-licensed and production-ready on its own.

Candlesticks with EMA(21/55) overlays, a volume pane, RSI and MACD subpanes and the range selector, on the onyx theme

Everything above is in this package: candlesticks, EMA overlays, volume, RSI and MACD subpanes, the crosshair readout and the range selector, on the built-in onyx theme. Synthetic data.


Why Tickwick

  • Drop-in widget<TickwickChart data={...} /> in React or Vue, or mount imperatively with TickwickChart.create({ container, data }) anywhere else.
  • No heavyweight dependencies — four granular d3 modules and nothing else. The scales, the gesture recogniser and the whole indicator library are local.
  • Declarative configs — describe panes, indicators and layout as plain JSON, which suits LLM "prompt-to-chart" flows.
  • Extensible — register custom themes, indicators, drawing tools and chart types at runtime through the plugin API. No fork required.

What's in this package

tickwick is the free tier and is fully usable in production under MIT. Counts come from FEATURES.md in the source repository, the source of truth for every published claim.

| Area | Included | |------|----------| | Chart styles | Candlestick, line, area | | Indicators | The 14 classics — SMA, EMA, WMA, MACD, RSI, Stochastic, CCI, Williams %R, ROC, Bollinger Bands, ATR, ADX, OBV, Volume | | Drawing tools | Line, horizontal line, text | | Themes | All 10onyx, carbon, aurora, midnight, dracula, nord, graphite (dark); daylight, parchment, solarized (light) — plus unlimited custom themes | | Interaction | Pan, zoom, pinch, wheel, crosshair, OHLCV tooltip | | Layout | Main pane + indicator subpanes; comparison overlays (percent change) | | i18n | English. setMessages() supplies your own strings; the other nine languages are a Pro feature | | Watermark | "Powered by Tickwick", shown by default. A plain option, not a licence gate — showWatermark: false hides it |

Theming is not a paywall. Both tiers get all 10 bundled themes, all 37 theme tokens and registerTheme().

The same chart on four of the ten bundled themes — onyx and aurora (dark), daylight and parchment (light)


Install

npm install tickwick

Styles are needed once, in your app entry:

import 'tickwick/style.css';

Peer dependencies. react and vue are both optional peers, needed only if you import the matching wrapper (tickwick/react / tickwick/vue). Vanilla and Svelte users install neither.

Supported browsers: Chrome 87+, Edge 88+, Firefox 78+, Safari 14+ (also declared in browserslist). Node 18.18+ is required to build from source.


Quick start

React

import { TickwickChart } from 'tickwick/react';
import 'tickwick/style.css';

export default function App({ data }) {
  return <TickwickChart data={data} theme="onyx" height={480} />;
}

Mounting, prop syncing and teardown are handled for you. A ref gives you the live instance (updateData, setTheme, setLocale, setOptions, destroy).

Vue 3

<script setup>
import { TickwickChart } from 'tickwick/vue';
import 'tickwick/style.css';

defineProps(['data']);
</script>

<template>
  <TickwickChart :data="data" theme="onyx" :height="480" />
</template>

Vanilla JavaScript

import { TickwickChart, sampleBtcData } from 'tickwick';
import 'tickwick/style.css';

const chart = TickwickChart.create({
  container: document.getElementById('chart'),
  data: sampleBtcData,
  theme: 'onyx',
  height: 480,
});

// You own the lifecycle here — the wrappers do this for you.
chart.destroy();

destroy() tears down the widget and restores the container's inline styles, so the element is reusable afterwards.

Svelte

The widget is a Svelte 4 component internally, but the public API is the same imperative one — use TickwickChart.create() in onMount and return chart.destroy for cleanup.


Indicators and panes

Add indicators as overlays on the price pane or as their own subpane:

TickwickChart.create({
  container: '#chart',
  data,
  theme: 'daylight',
  panes: [
    {
      type: 'candles',
      indicators: [
        { type: 'EMA', period: 21 },
        { type: 'BollingerBands', period: 20, stdDev: 2 },
        { type: 'Volume' },
      ],
    },
    { type: 'indicator', config: { type: 'RSI', period: 14 }, height: 110 },
  ],
});

EMA, Bollinger Bands and volume on the price pane with an RSI subpane, on the daylight theme


Data format

Each bar is an OHLCV tuple:

[timestamp, open, high, low, close, volume]
  • timestamp — Unix time in milliseconds. Second-resolution values are detected per row and normalised, so mixed input is fine.
  • open, high, low, close — prices.
  • volume — shares, contracts or normalised units.
const data = [
  [1609459200000, 29000, 29500, 28800, 29300, 1_000_000],
  [1609545600000, 29300, 30000, 29200, 29800, 1_200_000],
];

Rows must be time-ascending. normalizeOHLCV(rows) is exported if you want to coerce input once and reuse the result; the widget runs it on whatever you pass as data, so you rarely need it directly.

Demo data

import {
  generateRandomData,
  generateRealisticData,
  generateAlignedCompareData,
} from 'tickwick';

const random  = generateRandomData(500, 150, 0.02);        // points, start, volatility
const bullish = generateRealisticData(500, 150, 'bullish'); // 'bullish' | 'bearish' | 'sideways'

API overview

const chart = TickwickChart.create(config);

| Method | Purpose | |---|---| | updateData(rows) | Replace the dataset in place | | setTheme(name \| theme) | Switch theme live; a partial theme object is fine | | setLocale(code) | Switch this chart's locale (async — locales are lazy chunks) | | setMessages(messages) | Supply custom strings for this chart | | setOptions(partial) | Merge widget options live | | setEvents / addEvent / clearEvents | Event markers (rendered when the Pro renderer is present) | | destroy() | Tear down and restore the container |

| Static | Purpose | |---|---| | TickwickChart.create(config) | Primary constructor | | TickwickChart.createFromConfig(container, config) | Config-first form | | TickwickChart.getThemes() / getTheme(name) | Bundled palettes |

Locale is per chart. A chart follows the app-wide setLocale() until you give it one of its own via the locale option or chart.setLocale(), so several charts on one page can run in different languages.


Themes

import { registerTheme } from 'tickwick/plugin';

registerTheme('midnightBlue', {
  backgroundColor: '#0b1220',
  candleColorUp: '#22c55e',
  candleColorDown: '#ef4444',
  // …only the tokens you care about; the rest fall back to the default theme
});

chart.setTheme('midnightBlue');

A registered theme is available to every chart instance immediately. The full Theme contract (37 tokens) is exported from tickwick/theme.

Use the canonical token names. An unrecognised key is silently ignored rather than rejected, so a plausible-looking guess (upColor, panelBackground, yAxisGridColor) leaves that part of the chart on the default theme with no warning. Import the type and let TypeScript check the object:

import type { Theme } from 'tickwick/theme';

const brand: Partial<Theme> = { candleColorUp: '#22c55e' };

Plugin system

Register extensions without touching library source. Four registries back it — drawing tools, indicators, chart types and themes:

import { registerPlugin } from 'tickwick/plugin';

registerPlugin({
  name: 'my-plugin',
  themes: [{ name: 'myTheme', theme: { /* Theme */ } }],
  indicators: [
    {
      id: 'VWAP',
      label: 'VWAP',
      paneType: 'overlay',            // or 'separate' for its own subpane
      defaultConfig: { color: '#FF9800' },
      calculate(indicator, rows) {     // annotate each row in place
        for (const row of rows) row[indicator.uniqueId] = row[4];
      },
      // draw(indicator, indicatorRenderer, renderer) — the third arg is the
      // pane's ChartRenderer, needed only by `drawPaneSeries`.
      draw(indicator, indicatorRenderer) {
        indicatorRenderer.drawOverlaySeries(indicator, [{ key: null, color: indicator.color }]);
      },
    },
  ],
  drawingTools: [{ id: 'my-arrow', ctor: MyArrowDrawer }],
});

Granular entry points are also exported: registerTheme, registerIndicator, registerDrawingTool, registerChartType.


LLM / prompt-to-chart

ChartConfig is JSON-serialisable, so a model can emit one directly:

TickwickChart.createFromConfig('#chart', {
  data,
  theme: 'aurora',
  panes: [
    { type: 'candles', indicators: [{ type: 'SMA', period: 50 }, { type: 'RSI', period: 14 }] },
  ],
});

Use getAvailableThemes() and getSupportedIndicators() to build the tool schema you hand the model, so it can only name things this build actually has.


Script tag (UMD)

<link rel="stylesheet" href="https://unpkg.com/tickwick/dist/tickwick-widget.css" />
<script src="https://unpkg.com/tickwick/dist/tickwick-widget.umd.cjs"></script>
<script>
  // The UMD build exposes the module namespace as the global `TickwickChart`,
  // so the class itself is `TickwickChart.TickwickChart`.
  const chart = TickwickChart.TickwickChart.create({
    container: '#chart',
    data: TickwickChart.generateRandomData(500),
    theme: 'onyx',
    height: 600,
  });
</script>

The script-tag build ships English only — a UMD bundle cannot code-split, so the locale chunks are ES-build only. setMessages() still works.


Entry points

| Import | Purpose | |--------|---------| | tickwick | TickwickChart, data helpers, types | | tickwick/style.css | Widget styles | | tickwick/plugin | registerPlugin and the granular register* functions | | tickwick/react | React component | | tickwick/vue | Vue 3 component | | tickwick/theme | The Theme contract and the 10 bundled palettes |

Source subpaths

Beyond those, the package exposes internals — tickwick/ta, tickwick/data/DataHandler, tickwick/drawing/tools/BaseTool, tickwick/terminal/Terminal.svelte and friends — as raw .ts / .svelte source. They exist so plugins (including tickwick-pro) can build against the same types the library uses internally. Importing one requires a build setup that compiles TypeScript and Svelte from node_modules — Vite and SvelteKit do this out of the box; plain Node, Jest without a transform, or a bare webpack config will not. Treat them as a plugin-author surface, not part of the stable public API.


Documentation and links

| Where | What you'll find | |---|---| | docs.tickwick.co | Full documentation — guides, API reference, options, theming, plugin authoring | | tickwick.co | Project website | | tickwick.co/demo | Live interactive demo | | tickwick.co/playground | Build a config in the browser and copy the code | | tickwick.co/features | Feature-by-feature tour, free and Pro | | tickwick.co/components | The Pro terminal component library, live | | tickwick.co/ai | Prompt-to-chart / LLM integration | | tickwick.co/pricing | Tiers and licensing | | GitHub · Issues | Source, bug reports, feature requests | | npm | Published package and release history |


Contributing

npm install
npm run build       # ES + UMD bundles → dist/
npm run check       # svelte-check + tsc
npm run test:unit   # vitest

See CONTRIBUTING.md for the layout, the conventions worth knowing before you start, and what a reviewable change looks like. Security issues go through SECURITY.md — please don't open a public issue for those.


Pro edition (optional)

tickwick-pro is a commercial, licence-gated plugin that layers on 7 more chart types (10 in total), 115 more indicators (129 in total, including 23 candlestick patterns), 31 more drawing tools (34 in total), auto-analysis, event markers, backtesting, replay, export, workspaces and 9 more languages (10 in total), and removes the watermark. It also ships a terminal component library — 52 components (Watchlist, OrderBook, OrderTicket, OptionsChain, CandleChart, Backtest, …) — as a tree-shakeable bonus entry.

It peer-depends on tickwick and plugs in only after a valid licence verifies; with no licence it behaves exactly like the free widget. The OSS library is complete without it.

See the feature comparison, the component gallery or the Pro docs.


License

MIT © Tickwick