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

@lilt-ui/charts

v0.13.1

Published

Beautiful, key-typed React chart cards with linked hover, targets, forecasts, finance charts, and calm motion.

Readme

Install

npm install @lilt-ui/charts
# or: pnpm add @lilt-ui/charts
# or: yarn add @lilt-ui/charts
# or: bun add @lilt-ui/charts

Lilt needs React and React DOM 19. Every card, variant, and prop is documented at liltui.vercel.app. Import the stylesheet once, in your root layout or app entry:

import '@lilt-ui/charts/styles.css';

With an agent

Working with Claude Code, Cursor, or another coding agent? Paste this, then ask for the chart you want:

Use Lilt Charts (@lilt-ui/charts) for charts. Read https://liltui.vercel.app/llms.txt first and follow its rules.

llms.txt lists every card by job with its rules; llms-full.txt adds every example, data shape, and prop.

Your first card

'use client';

import { AreaChartCard } from '@lilt-ui/charts';

const visitors = [
  { month: 'Jan', organic: 2400, paid: 800 },
  { month: 'Feb', organic: 2800, paid: 700 },
  { month: 'Mar', organic: 3100, paid: 900 },
];

export function VisitorsCard() {
  return (
    <AreaChartCard
      title="Visitors"
      data={visitors}
      x="month"
      series={[
        { key: 'organic', label: 'Organic' },
        { key: 'paid', label: 'Paid' },
      ]}
    />
  );
}

The headline, value tiles, and hover come from your rows. Supply delta when you want a change chip, for example delta={0.082} for +8.2%. x and each series key are checked against your data, so a typo is a type error, not a blank chart.

Every card, finished

| For | Cards | | -------------------- | ----------------------------------------------------------------------------------------------- | | Trends | Area, Line, Bar, and Combo cards, overlapping, stacked, or as shares | | At a glance | Stat cards with a sparkline, bars, a meter, or a ring | | Parts and goals | Radial, Treemap, Progress, and Activity ring | | Rankings | Horizontal bar, with shares and an "Other" row | | Flows and change | Funnel, Sankey, and Slope | | Patterns | Heatmap (matrix and calendar), Scatter (points, strip, beeswarm), Radar | | Spread | Range (floating bars, error bars, timeline intervals) and Box plot | | Markets | Candlestick, Indicators, Price, Depth, Order book, and Portfolio | | Cool | 23 spatial families, from Skyline and Terrain to Chord loom, Sunburst terraces, and Voxel cloud |

Charts drawn in depth

Explore the Cool families: Skyline, Block city, Hex city, Voxel waffle, Terrain, Ridgeline, Spiral year, Event helix, Chord loom, Arc bridges, Rank ribbons, Parallel ribbons, Contour islands, Sunburst terraces, Cluster constellation, Ternary prism, Wind rose, Marimekko blocks, Intersection towers, Horizon folds, Circle archipelago, Helix ribbons, and Voxel cloud. Each is its own card with its own data contract.

Companion cards

TreemapChartCard reads label, value, and an optional group for one parent level. CalendarHeatmapCard reads date and value, with optional inclusive UTC from/to bounds. TimelineChartCard reads label, start, and end, and packs overlaps within optional lane categories. StripChartCard reads category and value; display="beeswarm" separates collisions without moving numeric positions.

They take the same depth, loading, empty, and header props as every other card, plus onSelectionChange and renderReadout for your own presentation. Treemap areas must be nonnegative, calendar dates are UTC, and timeline durations are measured in milliseconds (displayed as hours by default).

Existing family pages also cover StreamgraphCard, DivergingBarCard, MirroredBarCard, NestedDonutCard, ComparativeFunnelCard, GoalPacingCard, MilestoneProgressCard, ViolinCard, and CorrelationMatrixCard. Line supports indexed growth; Line and unstacked Area accept supplied forecast bands; Horizontal Bar supports lollipops; Scatter supports ordered trails; and Treemap supports group drill-down.

Finance charts

Candlesticks, indicators, and order books ship from their own entry point, so apps that never draw a candle never load one:

'use client';

import { CandlestickChartCard } from '@lilt-ui/charts/finance';

const candles = [
  {
    date: new Date('2026-08-20'),
    open: 243.1,
    high: 246.4,
    low: 241.8,
    close: 245.2,
    volume: 2410000,
  },
  {
    date: new Date('2026-08-21'),
    open: 245.2,
    high: 247.0,
    low: 243.9,
    close: 244.6,
    volume: 1980000,
  },
];

export function MarketCard() {
  return (
    <CandlestickChartCard
      title="SOL · USDC"
      data={candles}
      x="date"
      open="open"
      high="high"
      low="low"
      close="close"
      volume="volume"
      valueFormat={{ style: 'currency', currency: 'USD' }}
    />
  );
}

| Card | What it shows | | ---------------------- | ------------------------------------------------------------------------------ | | CandlestickChartCard | Candles, hollow candles, OHLC bars, or a price area, with a linked volume pane | | IndicatorChartCard | Moving averages or Bollinger bands over the price; RSI, MACD, or volume panes | | PriceChartCard | A ticker with its latest price and change, or several instruments rebased | | DepthChartCard | How much could trade at each price, buying and selling, and the gap between | | OrderBook | Resting orders level by level, the best prices meeting in the middle | | PortfolioChartCard | What an account is worth next to what went in, and its fall from its best |

Candles draw into a handful of paths however many there are, so years of daily history stay fast. scale="log" spaces long histories by ratio, and live follows new rows as they arrive. The indicator math (sma, ema, rsi, macd, bollinger, drawdown, depthLevels) is exported too, for your own layouts.

Built in, one prop away

  • Linked hover. Cards with sync, including Area, Line, Bar, Combo, and Stat, read the same moment together. Stat also needs x.
  • Targets and forecasts. On Area, Line, Bar, and Combo cards, target draws a goal line and counts the points that reach it. forecast marks supplied projected rows and keeps them out of the headline. Lilt does not estimate forecasts.
  • Pin and compare. On cards with inspection, click a mark to pin it; press off the marks, or Escape, to let go. Cards with compare let you drag across the plot to see what changed, in the headline or, with compare="badge", in the card's tab. Check the family's props for availability.
  • Honest data. null is a gap, never a zero, and missing values say so.
  • Loading and empty. loading shows a skeleton that "shimmer"s, "draw"s, or "breathe"s in the chart's own shape, then hands over to the data. A period with no rows shows a still empty state, or your own with empty, and the headline reads a dash, never zero.
  • Long series. Line and area cards draw tens of thousands of points from four per pixel column; hover, tiles, and exports still read every row.
  • Calm by default. Keyboard navigation, screen reader labels, and motion that respects reduced-motion settings.

Fits your design system

Omit title to render no visible title. header={false} removes the entire header, including the headline, delta and period controls. Cards with legend layouts accept legend={false} independently. surface="ghost" only removes the visual frame. Give embedded charts an aria-label; pass data directly when your app owns the period selector.

Cards with ranges draw Lilt's period select: a pill that opens a frosted list, with arrows, Home/End, Enter, Escape and type-ahead. To use your design system's select in every card instead, wrap them once:

import { ChartComponentsProvider, type ChartRangeSelectProps } from '@lilt-ui/charts';

function PeriodSelect({ value, options, onValueChange, ...rest }: ChartRangeSelectProps) {
  return (
    <Select value={value} onValueChange={onValueChange} aria-label={rest['aria-label']}>
      {options.map((option) => (
        <SelectItem key={option.id} value={option.id}>
          {option.label}
        </SelectItem>
      ))}
    </Select>
  );
}

<ChartComponentsProvider rangeSelect={PeriodSelect}>{children}</ChartComponentsProvider>;

Every card that pins works from the keyboard: Tab to the chart, arrows to inspect, Enter or Space to pin, and Escape to clear. Radial, Funnel, and Horizontal bar cards can hand their pin to you with a controlled selected; a click, Escape, or a press off the marks then asks onSelectedChange instead of changing it.

Cards follow shadcn theme variables when your app defines them: --card, --card-foreground, --muted-foreground, --border, --ring, and --chart-1 to --chart-5. Anything you leave out falls back to Lilt's own palette.

Every Lilt style lives in the lilt cascade layer, so your CSS wins without specificity tricks. With Tailwind, declare the layer order once at the top of your global stylesheet:

@layer theme, base, lilt, components, utilities;
@import 'tailwindcss';

License

MIT © Lilt UI