DitherCharts

Installation

Updated

DitherCharts copies chart source into your app, like shadcn/ui, so you own and can edit every line. You need Pro and a React 19 app with TypeScript. Tailwind and shadcn/ui are optional.

With the CLI

Log in once per machine. Your browser opens to confirm a code.

npx dithercharts login

Then add charts from your app's folder:

npx dithercharts add area-chart

Files land in src/components/dithercharts/ (or components/dithercharts/ without a src folder), and the CLI installs d3-scale and d3-shape. If your app has a tsconfig.json, it also adds @types/d3-scale and @types/d3-shape as dev dependencies. Import the stylesheet once, then use a chart:

import "@/components/dithercharts/dithercharts.css"
import { AreaChart } from "@/components/dithercharts/area-chart"

const data = [{ month: "jan", revenue: 18 }, { month: "feb", revenue: 26 }]
const config = { revenue: { label: "Revenue" } }

<AreaChart label="Monthly revenue" data={data} config={config} xKey="month" />

The form controls install the same way and need no dependencies. They bring their own stylesheet, controls.css, to import once beside the charts' one:

npx dithercharts add button select
import "@/components/dithercharts/controls.css"
import { Button } from "@/components/dithercharts/button"

<Button>Save</Button>

A chart fills its container's width. If the container is a flex item that doesn't stretch (auto margins or align-items: center), give it width: 100%, or the chart shrinks to fit its labels.

These examples import with the @/ alias for your source folder. shadcn/ui and Next.js apps already have it. The chart files import each other with relative paths, so only your own imports need the alias. To add it to a Vite app, put this in tsconfig.app.json under compilerOptions, and this in vite.config.ts:

// tsconfig.app.json
"paths": { "@/*": ["./src/*"] }

// vite.config.ts
resolve: { alias: { "@": "/src" } },

Or skip the alias and import relatively, for example from src/App.tsx: ./components/dithercharts/area-chart.

Other commands: list, whoami, logout. Pass --overwrite to replace files you changed, --no-install to print the package install command instead of running it. logout revokes this machine's key, and the server can keep accepting it for up to a minute afterwards.

Each login creates a key named CLI · <host> · <time> and revokes that machine's older keys, so logging in again replaces the key instead of adding one. To cut off a machine you no longer have, revoke its key by name in the account menu: Manage account → API keys.

In CI

Set DITHERCHARTS_API_KEY to a key from npx dithercharts login (saved in ~/.config/dithercharts/auth.json). The CLI uses it instead of a saved login. That key belongs to the machine you logged in on: a new login or a logout there revokes it, so update the CI secret afterwards.

From a zip

On your account page, download dithercharts.zip, unzip it into your components folder, and follow its README.

Styling

Charts read these CSS variables. Each falls back to the shadcn/ui token, then to a fixed default, so a shadcn/ui theme (including dark mode) applies with no setup.

VariableFalls back toUsed for
--dc-ink--foregroundMarks, text and the dither ink
--dc-paper--backgroundCanvas paper and tooltip background
--dc-line--borderGrid lines and borders
--dc-muted--muted-foregroundAxis labels and table headings
--dc-mono--font-monoLabels, tooltip and table font

Without shadcn/ui tokens, the chart falls back to its light defaults and stays light in dark mode. Set the --dc-* variables yourself. A stock Vite app already defines color variables, so map to those:

:root {
  --dc-ink: var(--text-h);
  --dc-paper: var(--bg);
  --dc-line: var(--border);
  --dc-muted: var(--text);
  --dc-mono: var(--mono);
}

With no color variables of your own, set light and dark values directly:

:root {
  --dc-ink: #1a1a1a;
  --dc-paper: #ffffff;
  --dc-line: #d4d4d4;
  --dc-muted: #737373;
}
@media (prefers-color-scheme: dark) {
  :root {
    --dc-ink: #f5f5f5;
    --dc-paper: #242424;
    --dc-line: #404040;
    --dc-muted: #a3a3a3;
  }
}

If dark mode is a class such as .dark, put the dark values under that class. The chart redraws when the color scheme or <html>'s class, style or data-theme changes.

Troubleshooting

MessageFix
Your key is invalid or revokedRun npx dithercharts login again.
No Pro licenseBuy Pro on the pricing page. Charts you already installed keep working.
This key can't install chartsThe key isn't a personal CLI key. Run npx dithercharts login to get one.
No chart named …Run npx dithercharts list to see the names.
… has local changes. Overwrite?You edited that file. Answer y to replace it, or keep yours.