GitHub

charts

Server-rendered SVG charts — no JavaScript, no external library. Pure functions that return SVG strings, composable with any layout component. All colours use design tokens and respond to light/dark theme.

Bar chart

Vertical bars with optional grid, value labels, and a zero baseline. All colour variants available.

023466891JanFebMarAprMayJun
barChart({
  data: [
    { label: 'Jan', value: 42 },
    { label: 'Feb', value: 78 },
    { label: 'Mar', value: 55 },
    { label: 'Apr', value: 91 },
    { label: 'May', value: 63 },
    { label: 'Jun', value: 84 },
  ],
  color: 'accent',
})

With value labels

02346689142Jan78Feb55Mar91Apr63May84Jun
barChart({ data, color: 'success', showValues: true })

Large dataset with tight gap

05251.1k1.6k2.1kMonTueWedThuFriSatSun
barChart({ data: traffic, color: 'blue', gap: 0.15 })

Negative values

-15-113274124Q1-8Q241Q3-15Q4
barChart({
  data: [
    { label: 'Q1', value:  24 },
    { label: 'Q2', value: -8  },
    { label: 'Q3', value:  41 },
    { label: 'Q4', value: -15 },
  ],
  color: 'warning',
  showValues: true,
})

Line chart

Connected data points with optional dots, area fill, and grid lines.

4254677991JanFebMarAprMayJun
lineChart({
  data: [
    { label: 'Jan', value: 42 },
    ...
  ],
  color: 'accent',
})

With area fill

4254677991JanFebMarAprMayJun
lineChart({ data, color: 'accent', area: true })

No dots, area fill, success colour

7201.1k1.4k1.8k2.1kMonTueWedThuFriSatSun
lineChart({ data, color: 'success', area: true, showDots: false })

Donut chart

Ring chart with multiple segments. Each item can override its colour. Pass label and sublabel for a centred annotation.

73%satisfied
donutChart({
  label:    '73%',
  sublabel: 'satisfied',
  data: [
    { label: 'Satisfied',   value: 73, color: 'success' },
    { label: 'Neutral',     value: 18, color: 'muted'   },
    { label: 'Unsatisfied', value: 9,  color: 'error'   },
  ],
})

Thinner ring

4segments
donutChart({
  size: 180, thickness: 22,
  label: '4', sublabel: 'segments',
  data: [
    { label: 'A', value: 40, color: 'accent'  },
    { label: 'B', value: 30, color: 'blue'    },
    { label: 'C', value: 20, color: 'success' },
    { label: 'D', value: 10, color: 'warning' },
  ],
})

Sparkline

Minimal inline trend line — pass a plain array of numbers. Designed to sit alongside stat() tiles or inside table cells.

sparkline({ data: [12,18,14,22,19,28,24,31], color: 'accent', area: true })
sparkline({ data: [31,24,28,19,22,14,18,12], color: 'error',  area: true })

Composition

Charts compose with card(), stat(), grid() — drop any chart into any content slot.

Monthly signups

023466891JanFebMarAprMayJun

Daily traffic

7201.1k1.4k1.8k2.1kMonTueWedThuFriSatSun
grid({
  cols: 2,
  content:
    card({ title: 'Monthly signups', content: barChart({ data, height: 180 }) }) +
    card({ title: 'Daily traffic',   content: lineChart({ data, color: 'blue', area: true, height: 180 }) }),
})

Sparkline in stat tiles

Revenue

$18.2k

+12%

Users

4,821

+8.4%

Churn

2.1%

−0.3%

card({
  content: stat({ label: 'Revenue', value: '$18.2k', change: '+12%', trend: 'up' }) +
    `<div style="margin-top:.75rem">${sparkline({ data, color: 'success', area: true })}</div>`,
})

Props

barChart()

PropTypeDefault
dataarray{ label, value }[]
heightnumber220SVG height in px
colorstring'accent'accent · success · warning · error · blue · muted
showValuesbooleanfalseValue labels above each bar
showGridbooleantrueHorizontal grid lines
gapnumber0.25Gap between bars as fraction 0–0.9

lineChart()

PropTypeDefault
dataarray{ label, value }[]
heightnumber220SVG height in px
colorstring'accent'accent · success · warning · error · blue · muted
areabooleanfalseFill area under the line
showDotsbooleantrueDots at each data point
showGridbooleantrueHorizontal grid lines

donutChart()

PropTypeDefault
dataarray{ label, value, color? }[] — color per segment
sizenumber200Diameter in px
thicknessnumber40Ring thickness in px
labelstringLarge centre text
sublabelstringSmaller text below centre label

sparkline()

PropTypeDefault
datanumber[]Plain array of numbers
widthnumber80SVG width in px
heightnumber32SVG height in px
colorstring'accent'accent · success · warning · error · blue · muted
areabooleanfalseFill area under the line