Introduction

Documentation Index

Fetch the complete documentation index at: /llms.txt. Use this file to discover all available pages before exploring further.

Open-source Svelte 5 chart components built with LayerChart and shadcn-svelte.

EvilCharts is a set of installable chart components, not a separate charting runtime. The Svelte port uses LayerChart for chart rendering and shadcn-svelte for its registry and UI conventions.

The Problem

Gurbinder created EvilCharts after seeing the same default chart styles repeated across products. The original project set out to make charts more distinctive without hiding their source code.

The words below are adapted from Gurbinder’s introduction to the original project. This port brings that work to Svelte.

There are tons of chart libraries, but none are beautiful. They allow customization, yet everyone just ships the defaults from the docs.

The result is an open-source chart component collection whose code belongs in your project.

Why is it called EvilCharts?

“Evil” doesn’t mean malicious. It means:

  • Unapologetically opinionated UI choices
  • Design-first, animated, unique designs
  • Handcrafted SVG and motion that give each chart a distinct look

One engine, every chart

Every chart is a compound component: the root owns the data and the config, and the visible parts are children. Same parts, same config object, same gradients, patterns and reveal animations across every chart type.

<EvilAreaChart {data} config={chartConfig}>
	<EvilAreaChart.Grid />
	<EvilAreaChart.XAxis dataKey="month" />
	<EvilAreaChart.Area dataKey="desktop" variant="gradient" />
</EvilAreaChart>

You install one chart at a time from this port’s registry, so you only ship what you choose. For example: npx shadcn-svelte@latest add https://evilcharts-sv.vercel.app/r/layerchart-area-chart.json.

Accessibility

Give each chart an accessible name with the root accessibility prop. Add a description when the chart needs context that its name does not provide.

<EvilAreaChart
	{data}
	config={chartConfig}
	accessibility={{
		label: 'Monthly traffic',
		description: 'Desktop and mobile visits from January through December.'
	}}
>
	<EvilAreaChart.Legend isClickable />
	<EvilAreaChart.Area dataKey="desktop" isClickable />
	<EvilAreaChart.Area dataKey="mobile" isClickable />
</EvilAreaChart>

If visible text already names or describes the chart, pass its element IDs as labelledBy and describedBy. The chart wrapper keeps role="group", so interactive legends and chart marks remain available to assistive technology.

LayerChart

SVG, and all of it is in the DOM. LayerChart renders through Svelte to SVG, so every gradient, pattern, dot and glow is a real element.

  • Themeable without JavaScript. Series colors compile to per-chart CSS variables, so light and dark modes swap with a class and do not need a re-render.
  • Inspectable. Open devtools and the whole chart is right there, stylable with the CSS you already use.
  • Composable. Charts are built from parts, not props. Drop in a <Grid />, a <Legend />, or a second <Area />.

Reach for it by default: product dashboards, marketing pages, anything where the chart is design surface first and data volume second.

Start with Installation . Labels, colors, and icons come from one object, which is covered in Chart Config .

Credits and licence

Original projectlegions-developer/evilcharts
Original siteevilcharts.com
Original authorGurbinder
LicenceMIT, for both the original and this port
Svelte portmielsense/evilcharts-sv
Port authorMathis

Substantially all of the design, component API, documentation prose and example data in this port derive from the original project. The Svelte translation uses LayerChart, @humanspeak/svelte-motion, and Svelte 5 in place of the original React stack.