Why charts without a charting library

Most component libraries either omit charts or wrap Recharts, which is roughly 100 kB before you render anything. For a dashboard with two sparklines and a bar chart, that is an enormous amount of JavaScript to display what is fundamentally a handful of `<path>` elements.

The six chart types here are inline SVG with no charting dependency, totalling 8.3 kB minified and brotlied. The CSS lives at a separate subpath so applications with no charts download nothing extra — `charts.css` is 10.1 kB raw and 2.0 kB gzipped.

A table fallback, not alt text

A chart is a visual encoding of numbers. A screen reader user does not need a description of the shape, they need the numbers. So every chart renders a real `<table>` fallback carrying the actual data.

This is meaningfully better than a text summary. 'Revenue rose over the quarter' is an interpretation; a table is the data, and the user draws their own conclusion exactly as a sighted reader does from the plot. It is also indexable, which is a side benefit worth having on a public page.

Never colour alone

Around one in twelve men has some form of colour vision deficiency. A chart legend that distinguishes three series purely by hue is unreadable for a meaningful share of your audience, and the failure is silent — they will not report it, they will just misread the chart.

So every series carries a distinct dash pattern and a distinct marker shape in addition to colour, on a colourblind-safe palette with a lifted ramp for dark mode. Redundant encoding is the whole technique: any single channel can be lost and the chart still parses.

Feeding it your data

The API takes an array of data objects and a `series` array describing which keys to plot and what to label them. `<LineChart data={revenue} series={[{ key: 'y', label: 'Revenue' }]} height={280} showGrid />` is a complete chart.

Keeping series configuration separate from data means you can plot several series from the same rows without reshaping them, and your data can stay in whatever shape your API returns. Charting libraries that require a specific row format push a transformation step into every component that uses them.

Why SVG rather than canvas

SVG elements are real DOM nodes: inspectable in devtools, styleable with CSS, and reachable by assistive technology. Canvas is a bitmap — faster for tens of thousands of points, and completely opaque to everything except sighted users.

For dashboards, the point counts are usually in the hundreds and SVG is comfortably fast enough. If you are plotting a hundred thousand points in real time, canvas or WebGL is the right tool and these charts are not what you want. That is a genuine limit rather than something to work around.

Where these charts stop

Six types cover the large majority of product dashboards: trends, comparisons, composition, sparklines and progress. They do not cover geographic maps, network graphs, candlesticks, box plots or anything statistical beyond the basics.

If you need those, a dedicated charting library is the right answer and paying its bundle cost is justified because you are using its depth. The argument here is only that most dashboards never needed that depth and paid for it anyway.

Key takeaways

  • Six chart types in 8.3 kB total as inline SVG, against roughly 100 kB for a typical charting library
  • charts.css is a separate subpath at 2.0 kB gzipped, so chart-free apps pay nothing
  • Every chart renders a real table fallback — the numbers, not an interpretation of them
  • Series are distinguished by dash pattern and marker shape as well as colour, on a colourblind-safe palette
  • SVG keeps charts inspectable, styleable and accessible; canvas is faster but opaque
  • For maps, network graphs or statistical plots, use a dedicated library — this covers product dashboards

Conclusion

Most dashboard charts are a few hundred points rendered as paths, and paying 100 kB for that is a habit rather than a requirement. What actually matters is that the numbers reach everyone — which is why the table fallback and the redundant encoding are not extras here.

Enjoyed this article?

Vivek Kumar Singh

Vivek Kumar Singh

Technical Expert · Full Stack Cloud Engineer · Tokyo, Japan