SVG renderer benchmark

novasvg vs. Chromium (ground truth), novasvg, resvg, lunasvg, cairosvg, thorvg, nanosvg — 14 samples, each rendered at its own aspect ratio (fit within 320×320px), median of 5 runs per cell. Generated 2026-09-24 18:27 UTC.

Chromium (ground truth) is the reference every other engine is checked against, not a competitor — its render time includes full browser page-navigation overhead (one shared instance for the whole corpus, one render each, no median-of-N) and isn't meant to be compared against the others' numbers. Under each other render, RMSE (root mean squared error against the ground-truth render, same pixel dimensions, all 4 RGBA channels, back on the 0-255 scale) gives a rough sense of how visually close it landed — squaring before the square root weights a handful of badly-wrong pixels (a missing filter, a wrong fill, a shifted shape) far more than the routine anti-aliasing noise along every edge, so low single digits is essentially imperceptible and anything in the tens or higher usually means something structural differs.

nanosvg is included as a lightweight baseline, not a fair fight with the other 5 — it's a minimal path/gradient rasterizer with no CSS, no filters, and no text layout, so its FAILs and blank renders on filter- or text-heavy samples below are expected scope, not bugs.

Engine versions

EngineVersionRendered OKAvg time / sampleTotal time
Chromium (ground truth)Chromium 141.0.7390.3714/1470.77 ms990.75 ms
novasvg0.3.014/147.10 ms99.38 ms
resvg0.45.114/142.71 ms38.01 ms
lunasvg3.5.014/143.76 ms52.63 ms
cairosvg2.9.114/1423.70 ms331.84 ms
thorvg1.0.014/140.75 ms10.50 ms
nanosvggit-master (no version macro upstream)14/143.04 ms42.58 ms

Rendered output

Same size (that sample's own aspect ratio, fit within 320×320px) from every engine, side by side, so visual differences (missing text, wrong fills, unapplied filters, ...) are easy to spot. Click any render to zoom in.

circle (320×320px)

plain shape

Chromium (ground truth) render of circle
Chromium (ground truth)
79.22 ms
reference
novasvg render of circle
novasvg
0.79 ms
RMSE 1.81
resvg render of circle
resvg
0.39 ms
RMSE 1.38
lunasvg render of circle
lunasvg
0.72 ms
RMSE 1.81
cairosvg render of circle
cairosvg
5.49 ms
RMSE 1.80
thorvg render of circle
thorvg
0.50 ms
RMSE 1.62
nanosvg render of circle
nanosvg
2.41 ms
RMSE 2.39

rect (320×320px)

plain shape

Chromium (ground truth) render of rect
Chromium (ground truth)
46.22 ms
reference
novasvg render of rect
novasvg
0.25 ms
RMSE 0.00
resvg render of rect
resvg
0.09 ms
RMSE 0.00
lunasvg render of rect
lunasvg
0.16 ms
RMSE 0.00
cairosvg render of rect
cairosvg
3.87 ms
RMSE 0.00
thorvg render of rect
thorvg
0.19 ms
RMSE 0.00
nanosvg render of rect
nanosvg
3.18 ms
RMSE 1.57

tiger (320×320px)

complex path-heavy vector art

Chromium (ground truth) render of tiger
Chromium (ground truth)
69.88 ms
reference
novasvg render of tiger
novasvg
16.90 ms
RMSE 5.96
resvg render of tiger
resvg
6.59 ms
RMSE 5.24
lunasvg render of tiger
lunasvg
19.38 ms
RMSE 5.96
cairosvg render of tiger
cairosvg
70.76 ms
RMSE 5.61
thorvg render of tiger
thorvg
6.21 ms
RMSE 5.91
nanosvg render of tiger
nanosvg
19.34 ms
RMSE 11.48

nova-logo (320×161px)

logo, mixed shapes/gradients

Chromium (ground truth) render of nova-logo
Chromium (ground truth)
39.20 ms
reference
novasvg render of nova-logo
novasvg
1.30 ms
RMSE 10.13
resvg render of nova-logo
resvg
0.89 ms
RMSE 8.40
lunasvg render of nova-logo
lunasvg
1.28 ms
RMSE 10.13
cairosvg render of nova-logo
cairosvg
9.23 ms
RMSE 9.22
thorvg render of nova-logo
thorvg
0.53 ms
RMSE 9.03
nanosvg render of nova-logo
nanosvg
1.75 ms
RMSE 25.05

clip-mask (320×160px)

clip-path + luminance mask

Chromium (ground truth) render of clip-mask
Chromium (ground truth)
41.68 ms
reference
novasvg render of clip-mask
novasvg
0.56 ms
RMSE 4.35
resvg render of clip-mask
resvg
0.94 ms
RMSE 6.26
lunasvg render of clip-mask
lunasvg
0.55 ms
RMSE 4.35
cairosvg render of clip-mask
cairosvg
3.43 ms
RMSE 97.46
thorvg render of clip-mask
thorvg
0.34 ms
RMSE 4.17
nanosvg render of clip-mask
nanosvg
1.42 ms
RMSE 118.00

gradient-filter (320×160px)

gradients + SVG filter

Chromium (ground truth) render of gradient-filter
Chromium (ground truth)
39.50 ms
reference
novasvg render of gradient-filter
novasvg
13.77 ms
RMSE 8.17
resvg render of gradient-filter
resvg
12.72 ms
RMSE 13.36
lunasvg render of gradient-filter
lunasvg
0.38 ms
RMSE 42.82
cairosvg render of gradient-filter
cairosvg
4.92 ms
RMSE 42.84
thorvg render of gradient-filter
thorvg
0.47 ms
RMSE 15.63
nanosvg render of gradient-filter
nanosvg
1.44 ms
RMSE 49.63

filter-primitives (320×120px)

chained filter primitives (blur/offset/flood/composite)

Chromium (ground truth) render of filter-primitives
Chromium (ground truth)
44.17 ms
reference
novasvg render of filter-primitives
novasvg
5.24 ms
RMSE 2.41
resvg render of filter-primitives
resvg
8.60 ms
RMSE 2.07
lunasvg render of filter-primitives
lunasvg
0.08 ms
RMSE 9.07
cairosvg render of filter-primitives
cairosvg
2.35 ms
RMSE 36.92
thorvg render of filter-primitives
thorvg
0.29 ms
RMSE 38.92
nanosvg render of filter-primitives
nanosvg
0.56 ms
RMSE 17.48

css-use-symbol (320×160px)

CSS transform + <use>/<symbol>

Chromium (ground truth) render of css-use-symbol
Chromium (ground truth)
32.53 ms
reference
novasvg render of css-use-symbol
novasvg
0.45 ms
RMSE 1.54
resvg render of css-use-symbol
resvg
0.34 ms
RMSE 26.32
lunasvg render of css-use-symbol
lunasvg
0.36 ms
RMSE 26.36
cairosvg render of css-use-symbol
cairosvg
3.98 ms
RMSE 26.35
thorvg render of css-use-symbol
thorvg
0.20 ms
RMSE 26.33
nanosvg render of css-use-symbol
nanosvg
0.52 ms
RMSE 69.54

base64-image (320×160px)

embedded raster <image>

Chromium (ground truth) render of base64-image
Chromium (ground truth)
49.16 ms
reference
novasvg render of base64-image
novasvg
1.15 ms
RMSE 24.61
resvg render of base64-image
resvg
1.64 ms
RMSE 18.98
lunasvg render of base64-image
lunasvg
1.10 ms
RMSE 24.67
cairosvg render of base64-image
cairosvg
3.98 ms
RMSE 28.86
thorvg render of base64-image
thorvg
0.16 ms
RMSE 93.30
nanosvg render of base64-image
nanosvg
1.36 ms
RMSE 93.30

mermaid-flowchart (273×320px)

<foreignObject> text, CSS classDef fills

Chromium (ground truth) render of mermaid-flowchart
Chromium (ground truth)
304.69 ms
reference
novasvg render of mermaid-flowchart
novasvg
9.72 ms
RMSE 12.38
resvg render of mermaid-flowchart
resvg
1.01 ms
RMSE 23.90
lunasvg render of mermaid-flowchart
lunasvg
4.13 ms
RMSE 25.25
cairosvg render of mermaid-flowchart
cairosvg
23.22 ms
RMSE 25.32
thorvg render of mermaid-flowchart
thorvg
0.48 ms
RMSE 39.77
nanosvg render of mermaid-flowchart
nanosvg
1.88 ms
RMSE 31.11

embedded-font (320×80px)

plain <text>, @font-face embedded TTF/OTF

Chromium (ground truth) render of embedded-font
Chromium (ground truth)
76.72 ms
reference
novasvg render of embedded-font
novasvg
18.35 ms
RMSE 37.41
resvg render of embedded-font
resvg
1.93 ms
RMSE 39.28
lunasvg render of embedded-font
lunasvg
10.53 ms
RMSE 44.29
cairosvg render of embedded-font
cairosvg
93.33 ms
RMSE 45.96
thorvg render of embedded-font
thorvg
0.23 ms
RMSE 39.28
nanosvg render of embedded-font
nanosvg
3.01 ms
RMSE 39.28

embedded-font-distinctive (320×112px)

embedded monospace font vs. an unresolvable family, side by side

Chromium (ground truth) render of embedded-font-distinctive
Chromium (ground truth)
69.79 ms
reference
novasvg render of embedded-font-distinctive
novasvg
16.62 ms
RMSE 55.83
resvg render of embedded-font-distinctive
resvg
1.59 ms
RMSE 48.42
lunasvg render of embedded-font-distinctive
lunasvg
10.36 ms
RMSE 58.28
cairosvg render of embedded-font-distinctive
cairosvg
76.18 ms
RMSE 58.52
thorvg render of embedded-font-distinctive
thorvg
0.21 ms
RMSE 48.42
nanosvg render of embedded-font-distinctive
nanosvg
2.42 ms
RMSE 48.42

mermaid-venn (320×180px)

plain shapes/text via <foreignObject> (mermaid venn diagram)

Chromium (ground truth) render of mermaid-venn
Chromium (ground truth)
49.82 ms
reference
novasvg render of mermaid-venn
novasvg
8.17 ms
RMSE 6.99
resvg render of mermaid-venn
resvg
0.55 ms
RMSE 16.28
lunasvg render of mermaid-venn
lunasvg
1.74 ms
RMSE 198.51
cairosvg render of mermaid-venn
cairosvg
15.53 ms
RMSE 198.39
thorvg render of mermaid-venn
thorvg
0.43 ms
RMSE 198.80
nanosvg render of mermaid-venn
nanosvg
1.85 ms
RMSE 207.54

mermaid-block (320×154px)

<foreignObject> text + CSS classDef fills (mermaid block diagram)

Chromium (ground truth) render of mermaid-block
Chromium (ground truth)
48.16 ms
reference
novasvg render of mermaid-block
novasvg
6.12 ms
RMSE 3.77
resvg render of mermaid-block
resvg
0.73 ms
RMSE 8.48
lunasvg render of mermaid-block
lunasvg
1.86 ms
RMSE 203.35
cairosvg render of mermaid-block
cairosvg
15.57 ms
RMSE 203.35
thorvg render of mermaid-block
thorvg
0.27 ms
RMSE 235.74
nanosvg render of mermaid-block
nanosvg
1.44 ms
RMSE 201.19