Give your data
a little Lilt.

Expressive chart cards. Thoughtful interactions.
Ready for your next interface.

npm install @lilt-ui/charts

Sales

$412,700+1.5%
Last 30 days

The looks

One chart.
Every look.

Scroll, and the card restyles itself. Every step is one prop, and every control is yours to play with.

  1. 01

    Palette

    Three palettes, each tuned for light and dark. Series take their colours in order.

  2. 02

    Bar style

    Cells, like the level meter it arrived as, or solid, a fade or a line.

  3. 03

    Depth

    One word stands the bars up in 3D, lit from one side, and hover still lands exactly.

  4. 04

    Surface

    Raised, outlined or ghost, so the card sits on whatever page you put it on.

  5. 05

    Loading

    A first load breathes, draws or shimmers, then the data lands on that same card.

Sales

$412,700+1.5%
Last 30 days
<BarChartCarddata={sales}x="date"series={series}stackbarStyle="segmented"/>

Interactions

Follow the data.
Every card listens.

This is the chart you just styled. Hover it, drag across it, look ahead. The interactions ship inside the card.

Sales

$412,700+1.5%
Last 30 days

Orders

4,910+4.2%
Last 30 days

syncMove across either card. Sales and orders follow the same day.

Linked hover docs

In code

Your chart.
In a few lines.

This is the source for the chart you built on the way down. The lines you chose are marked; copy it as it stands.

  • Hover & keyboard
  • Loading states
  • Light & dark
  • Screen readers
'use client';

import { BarChartCard } from '@lilt-ui/charts';
import '@lilt-ui/charts/styles.css';

const dailySales = [
  { "date": new Date('2026-03-22T00:00:00.000Z'), "newUsers": 4200, "existing": 9800 },
  { "date": new Date('2026-03-23T00:00:00.000Z'), "newUsers": 5600, "existing": 10400 },
  { "date": new Date('2026-03-24T00:00:00.000Z'), "newUsers": 4800, "existing": 8100 },
  { "date": new Date('2026-03-25T00:00:00.000Z'), "newUsers": 4300, "existing": 7200 },
  { "date": new Date('2026-03-26T00:00:00.000Z'), "newUsers": 5100, "existing": 9300 },
  { "date": new Date('2026-03-27T00:00:00.000Z'), "newUsers": 4900, "existing": 10100 },
  { "date": new Date('2026-03-28T00:00:00.000Z'), "newUsers": 3400, "existing": 6800 },
  { "date": new Date('2026-03-29T00:00:00.000Z'), "newUsers": 3100, "existing": 5700 },
  { "date": new Date('2026-03-30T00:00:00.000Z'), "newUsers": 5800, "existing": 9100 },
  { "date": new Date('2026-03-31T00:00:00.000Z'), "newUsers": 5200, "existing": 8300 },
  { "date": new Date('2026-04-01T00:00:00.000Z'), "newUsers": 4400, "existing": 7200 },
  { "date": new Date('2026-04-02T00:00:00.000Z'), "newUsers": 5000, "existing": 9900 },
  { "date": new Date('2026-04-03T00:00:00.000Z'), "newUsers": 4700, "existing": 10200 },
  { "date": new Date('2026-04-04T00:00:00.000Z'), "newUsers": 4100, "existing": 6700 },
  { "date": new Date('2026-04-05T00:00:00.000Z'), "newUsers": 3600, "existing": 5300 },
  { "date": new Date('2026-04-06T00:00:00.000Z'), "newUsers": 6400, "existing": 11400 },
  { "date": new Date('2026-04-07T00:00:00.000Z'), "newUsers": 5900, "existing": 9600 },
  { "date": new Date('2026-04-08T00:00:00.000Z'), "newUsers": 4800, "existing": 8000 },
  { "date": new Date('2026-04-09T00:00:00.000Z'), "newUsers": 4500, "existing": 11500 },
  { "date": new Date('2026-04-10T00:00:00.000Z'), "newUsers": 5700, "existing": 10200 },
  { "date": new Date('2026-04-11T00:00:00.000Z'), "newUsers": 4600, "existing": 7600 },
  { "date": new Date('2026-04-12T00:00:00.000Z'), "newUsers": 4300, "existing": 5900 },
  { "date": new Date('2026-04-13T00:00:00.000Z'), "newUsers": 6200, "existing": 11600 },
  { "date": new Date('2026-04-14T00:00:00.000Z'), "newUsers": 5800, "existing": 10900 },
  { "date": new Date('2026-04-15T00:00:00.000Z'), "newUsers": 5400, "existing": 9800 },
  { "date": new Date('2026-04-16T00:00:00.000Z'), "newUsers": 5100, "existing": 8600 },
  { "date": new Date('2026-04-17T00:00:00.000Z'), "newUsers": 5900, "existing": 10400 },
  { "date": new Date('2026-04-18T00:00:00.000Z'), "newUsers": 5200, "existing": 9900 },
  { "date": new Date('2026-04-19T00:00:00.000Z'), "newUsers": 3900, "existing": 6600 },
  { "date": new Date('2026-04-20T00:00:00.000Z'), "newUsers": 5600, "existing": 9100 },
];

export function Sales() {
  return (
    <BarChartCard
      title="Sales"
      data={dailySales}
      valueFormat={{ "style": "currency", "currency": "USD", "maximumFractionDigits": 0 }}
      x="date"
      series={[
        { "key": "newUsers", "label": "New users" },
        { "key": "existing", "label": "Existing users" },
      ]}
      stack
      barStyle="segmented"
      radius={2}
      delta={0.015}
      range="Last 30 days"
      palette="iris"
      depth={false}
      surface="elevated"
      sync="home-sales"
    />
  );
}

Sales

$412,700+1.5%
Last 30 days
The same card, drawn by the code beside it.

Scale

And when your data grows?

points. Still a light touch.

Your browserHover the chart

Requests per minute

2,183
Rows
100,800
Drawn
4 per pixel
Inspected
Every row
Span
10 weeks

Ten weeks. Every minute. A launch in week six, one incident after. Scrub through it.
The area draws four points per pixel; hover, keys and exports keep every row.

Run the benchmark

Families

From a quiet trend line to a retention grid, every family is one card that speaks the same props.

All chart families

Give your next interface
a little Lilt.

npm downloads

3,109

since Sep 28

GitHub stars1View on GitHub ↗
npm install @lilt-ui/charts