Engine-native charts: BarChart, LineChart, PieChart, AreaChart, and DotPlot
Charts are now rendered directly by the Rust engine as PDF vector graphics. Five chart types, multi-series support, and zero external dependencies.
Forme 0.7.13 moves chart rendering from the React layer into the Rust engine. Instead of generating intermediate SVG that the engine then converts to PDF drawing commands, charts now produce native PDF vector primitives directly. The result is the same crisp output with less overhead and more control.
What changed
Previously, <BarChart>, <LineChart>, and <PieChart> were React components that returned <View> + <Svg> + positioned <Text> children. The engine saw generic nodes and converted SVG shapes to PDF. That worked, but it meant chart logic lived in JavaScript, added node tree overhead, and couldn't take advantage of engine-level optimizations.
Now, the engine has five first-class NodeKind variants: BarChart, LineChart, PieChart, AreaChart, and DotPlot. Each chart type has a dedicated builder module in Rust that computes geometry and emits a flat list of drawing primitives — rectangles, lines, polylines, filled paths, circles, arc sectors, and text labels. The PDF renderer iterates these primitives and writes them directly to content streams.
Five chart types
BarChart
Category bar chart with optional grid lines, value labels, and a title.
import { BarChart } from '@formepdf/react';
<BarChart
width={400}
height={200}
data={[
{ label: 'Q1', value: 142000 },
{ label: 'Q2', value: 186000 },
{ label: 'Q3', value: 164000 },
{ label: 'Q4', value: 228000 },
]}
color="#3b82f6"
showGrid
showValues
title="Quarterly Revenue"
/>
LineChart
Multi-series line chart. Pass an array of series, each with its own name, data, and color.
import { LineChart } from '@formepdf/react';
<LineChart
width={500}
height={200}
series={[
{ name: 'Active Users', data: [1200, 1800, 2400, 3100, 3800, 4200], color: '#3b82f6' },
{ name: 'New Signups', data: [400, 600, 800, 900, 1100, 1000], color: '#10b981' },
]}
labels={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']}
showPoints
showGrid
title="User Growth"
/>
Note the API change: LineChart now takes series and labels instead of the old data + color props. This enables multiple lines with distinct colors in a single chart.
PieChart
Pie or donut chart with an optional legend.
import { PieChart } from '@formepdf/react';
<PieChart
width={200}
height={200}
data={[
{ label: 'Subscriptions', value: 62, color: '#3b82f6' },
{ label: 'Enterprise', value: 28, color: '#0f172a' },
{ label: 'Services', value: 10, color: '#94a3b8' },
]}
donut
showLegend
/>
The donut boolean replaces the old innerRadius prop. The showLegend prop replaces showLabels.
AreaChart (new)
Like LineChart but with semi-transparent fill under each line. Useful for showing cumulative trends.
import { AreaChart } from '@formepdf/react';
<AreaChart
width={500}
height={200}
series={[
{ name: 'Organic', data: [500, 800, 1200, 1800, 2600, 3200], color: '#3b82f6' },
{ name: 'Paid', data: [200, 400, 600, 900, 1100, 1400], color: '#f59e0b' },
]}
labels={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']}
showGrid
title="Traffic Sources"
/>
DotPlot (new)
Scatter plot for (x, y) data points grouped by category. Good for comparing distributions or performance metrics across versions.
import { DotPlot } from '@formepdf/react';
<DotPlot
width={300}
height={200}
groups={[
{ name: 'API v1', color: '#3b82f6', data: [[10, 45], [50, 120], [100, 230]] },
{ name: 'API v2', color: '#10b981', data: [[10, 25], [50, 60], [100, 110]] },
]}
xLabel="Concurrent Requests"
yLabel="Latency (ms)"
showLegend
dotSize={3.5}
/>
How it works under the hood
Each chart component in @formepdf/react is an intrinsic element — it returns null during React rendering and is serialized directly to the engine's JSON format. The Rust engine receives the chart node, calls the appropriate builder, and gets back a Vec<ChartPrimitive>:
pub enum ChartPrimitive {
Rect { x, y, w, h, fill },
Line { x1, y1, x2, y2, stroke, width },
Polyline { points, stroke, width },
FilledPath { points, fill, opacity },
Circle { cx, cy, r, fill },
ArcSector { cx, cy, r, start_angle, end_angle, fill },
Label { text, x, y, font_size, color, anchor },
}
The PDF renderer iterates this list inside a coordinate transform that flips Y (PDF uses bottom-left origin; charts use top-left). Each primitive maps to a few PDF operators: re f for rectangles, m l S for lines, cubic beziers for arcs and circles, BT/Tf/Td/Tj/ET for labels. Labels use Helvetica, which is always available in the engine's font system.
Migration from 0.7.12
If you're using the old chart API, here's what changed:
| Old prop | New prop | Component |
|---|---|---|
data (on LineChart) |
series + labels |
LineChart |
color (on LineChart) |
per-series color |
LineChart |
showDots |
showPoints |
LineChart |
showArea |
use <AreaChart> |
— |
innerRadius |
donut (boolean) |
PieChart |
showLabels |
showLegend |
PieChart |
barGap |
removed (auto-computed) | BarChart |
yAxisTicks |
removed (auto-computed) | BarChart, LineChart |
The old SVG-based implementations are still available as LegacyBarChart, LegacyLineChart, and LegacyPieChart if you need them during migration.
Python SDK
All five chart types are available in the Python SDK:
from formepdf import BarChart, LineChart, PieChart, AreaChart, DotPlot
chart = BarChart(
width=400,
height=200,
data=[
{"label": "Q1", "value": 142000},
{"label": "Q2", "value": 186000},
],
color="#3b82f6",
show_grid=True,
)
Try it
Update to 0.7.13:
npm install @formepdf/react@latest @formepdf/core@latest
Check out the templates/charts-showcase.tsx file in the repo for a two-page example using all five chart types together.