Apache-2.0 Rust · WebAssembly · runs in your browser

Inkvec Studio

Inkvec is an open-source raster-to-vector tracer: a Rust program compiled to WebAssembly that runs entirely inside the page you are reading. It is not a model and it has no weights — it is a deterministic optimiser, so the same input produces the same SVG every time.

0.132
Mean ΔE00 across the 21-case tracing suite
4.4×
Fewer coordinates than VTracer at defaults
3.27 MB
WebAssembly engine, downloaded once and cached
Apache-2.0
Open source, weights-free, reproducible
What Inkvec is

A tracer, not a guess

Inkvec reads a bitmap and writes an SVG. That is the whole job. The Rust source is compiled to WebAssembly and shipped to your browser, so the image never leaves your device — there is no upload step because there is no server side to upload to.

It is worth being blunt about what it is not: there is no neural network in it, no trained weights, no inference. Nothing about the output is sampled or generated. Every step is an optimisation problem with a defined objective, which is why running the same file twice gives you the same coordinates twice.

The licence is Apache-2.0, the repository is public, and the benchmark harness that produced the tables on this page ships inside it.

The method

How raster-to-vector tracing actually works here

Five stages, in this order. The interesting part is that the geometry is fitted against the rendered result, not against the pixel grid.

  1. 01

    Planar map construction

    The bitmap is decomposed into a planar map: regions, the boundaries between them, and the points where boundaries meet. Topology first, geometry after.

  2. 02

    Palette clustering

    Colours are clustered into a discrete palette, so a region is one ink rather than a gradient of near-identical samples.

  3. 03

    Boundary optimisation

    Each boundary is moved into place by nonlinear conjugate gradient descent, minimising the colour error of the rendered result rather than snapping to pixel edges.

  4. 04

    Curve fitting

    Dynamic programming chooses where the curve segments go. The number of coordinates is decided by minimum description length — not by a tolerance slider you have to guess at.

  5. 05

    SVG emission

    The result is written as ordinary SVG. A circle comes back as a <circle>, not as sixteen cubic Bézier segments pretending to be one.

Shapes stay shapes

A circle in the bitmap comes back as a <circle> element. Downstream tools, editors and minifiers can all still tell what it is.

No tolerance slider to guess at

How many coordinates a path deserves is chosen by minimum description length — the point where extra coordinates stop paying for themselves in accuracy.

Published figures

Tracing benchmark

21 cases: 14 real icons hash-selected across seven families, 4 synthetic probes, and 3 real brand logos. The selection is fixed by the seed crosscompare-2026-09-15-v1, so it cannot be quietly re-rolled into a flattering sample. ΔE00 is the CIEDE2000 colour difference between the rendered SVG and the source bitmap; lower is closer.

Tracing benchmark: mean and median colour error, coordinate count and run time for four engines across 21 cases.
EngineMean ΔE00 ↓Median ΔE00 ↓CoordinatesTime
Inkvec0.1320.054446 (1×)1.17 s
VTracer (default)1.3030.5981,943 (4.4×)0.04 s
VTracer (tuned)1.2640.5791,239 (2.8×)0.06 s
Trazor0.5180.2271,172 (2.6×)2.19 s

These are published figures for that corpus. They describe those 21 files — not yours.

The trade, stated plainly

Inkvec is roughly 10× more colour-accurate than VTracer, and roughly 25× slower.

That is the whole bargain, and it is not always worth taking. If you are tracing a folder of files, or anything where four hundredths of a second per image matters, VTracer remains the right tool and we would use it ourselves.

The 3 brand logos are not redistributable, so they are not in the repository. A clean clone reproduces the other 18 cases.

Published figures

Minifier benchmark

40 artist-drawn SVGs, with ΔE00 measured against the artist's own file rendered at 1024 px. For scale: the tracer's own error on these same files is 0.148, and around 1.0 is where a trained eye starts to notice a difference at all.

Minifier benchmark: bytes saved, mean colour error and worst-case colour error for four settings across 40 files.
TierBytes savedMean ΔE00Worst ΔE00
Lossless (--bytes-only)14.9%00
Rounded, 2 dp19.1%0.00840.0572
Refit, 0.1 px (default)23.5%0.00770.0362
Refit, 0.5 px36.9%0.05560.1779

Published figures for that corpus. They describe those 40 files — not yours.

Refitting beats rounding

The default setting saves more bytes than rounding to 2 decimals and lands closer to the original at the same time. Rounding has no way of knowing whether a coordinate is holding a corner in place; refitting does, so it spends its precision where the drawing needs it.

Rounding harder eventually saves less

Going from 2 decimals to 1 drops the saving to 14.5%. Past a point the output stops reading back as the same drawing, and the guard refuses it — so the aggressive setting ships the conservative result.

Against SVGO, and with it

Over nine files, compared with SVGO 4 at its defaults:

Bytes saved by SVGO alone, Inkvec alone, and the two chained, over nine files.
PipelineBytes saved
SVGO 4 alone, at defaults29.7%
Inkvec's minifier alone33.5%
SVGO 4, then Inkvec44.1%

Chaining wins because the two tools are not doing the same job. SVGO reads the markup: it collapses attributes, drops metadata, tidies stylesheets and rewrites transforms — but it cannot know that sixteen cubic segments are, geometrically, a circle. Inkvec works the other way round: it refits the geometry and leaves stylesheets, transforms and <defs> alone.

SVGO is excellent and deserves the credit: it is MIT-licensed and lives at github.com/svg/svgo. Where Inkvec implements an equivalent markup rule, that rule was re-implemented rather than copied, and the debt is recorded in the repository's NOTICE file.

Honest limits

Where it does badly

Nothing on this list is a roadmap item in disguise. These are properties of the method.

Photographs

Natural colour transitions break the discrete-ink model. Expect severe banding and enormous coordinate counts. Trace graphics, not photos.

Text

Glyphs become Bézier contours like anything else. There is no font detection, no OCR, and no <text> element in the output.

Variable-width strokes

Stroke recovery needs a uniform width. Rough sketches and brush work fall back to filled outlines.

Speed

The global optimisation is heavy: roughly a second per graphic natively, and tens of seconds in a browser. A 512 px preview measured about 13 seconds on a 16-core desktop. The engine runs single-threaded here on purpose — the threaded build needs cross-origin isolation, which would break other things on this site.

Engine download

The first trace or minify on a fresh browser pulls a 3.27 MB WebAssembly module. It is cached afterwards.

The two tools

Both run in your browser, both are free

Vectorizer

Traces a PNG or JPG into an SVG with the pipeline described above, entirely in your browser.

Reach for it when you have a flat logo or icon as a bitmap and need geometry you can scale, recolour and hand to a printer.

Open the Vectorizer

Minifier

Shrinks an SVG losslessly, or refits its curves within a tolerance you choose — with a guard that refuses any output that stops reading back as the same drawing.

Reach for it when an SVG is already good and simply too heavy for the page it sits on.

Open the Minifier
The project

Open source, licence and all

Inkvec is released under Apache-2.0: read it, fork it, ship it in your own product. The benchmark harness, the seed and the corpus manifest are all in the repository, so every table on this page can be re-run rather than taken on trust.

github.com/logolabs/inkvec Apache-2.0 · Rust compiled to WebAssembly · no weights, no uploads