Raster image (PNG, JPEG) to SVG converter, entirely in your browser
45
stars
189
commits
TypeScript
primary language
Sep 4, 2026
updated
Raster → SVG, entirely in your browser. A vectorization studio that turns PNG/JPEG/WebP/GIF/BMP images into clean, editable, cuttable SVG — with no server, no upload, no account. Host it on any static host (GitHub Pages included); your images never leave the machine.

Because the tracing algorithm is the product. Trazor implements a full Potrace-class curve chain (from Peter Selinger's 2003 paper — clean-room, no GPL code) and applies it per color layer, not just to black & white:
On top of that, three things most tracers don't do:
cutout layering the color segmentation's
boundary network is fitted once — every edge shared by two regions is a
single curve reused by both (with junction points pinned exactly). Adjacent
shapes are mathematically identical along their shared border: no hairline
gaps, no overlaps, ever. Ideal for cutting machines, screen printing and
clean editing.stacked (layers extend underneath — crack-proof, great for
illustration) or cutout (exact seam-free partition).pixel —
pixel-perfect rectilinear paths that keep sprite art exact.<linearGradient>/<radialGradient> instead of posterized bands — mesh-free
(geometry unchanged, cutout stays seam-free), fewer shapes, no banding.
Experimental and off by default; enable "Gradient fills" in the palette
settings.<g> sheet per color, mm units),
Laser engrave, Pen plotter (centerline, for line art), Stencil
(island detection warns about pieces that would fall out).<rect>/<circle> detection, and circular-arc A fitting that collapses
near-circular Bézier runs to exact arcs), group-by-color (one <g> layer per color
so cut/print tools separate sheets automatically), tiny-feature warnings below
cuttable size.N) that draws every path's anchor
points, Bézier handles and outlines — color-coded by element kind (traced
paths vs. rect/circle/ellipse primitives, with a legend) so you can see
the traced geometry's complexity at a glance, per-stage timings, palette
swatches, node/path/byte stats, download / copy / data-URI export, dark &
light themes, keyboard shortcuts..json file, and import it back by paste or file — share a
recipe or move it between machines. Everything stays local.npm install
npm run dev # Vite dev server
npm run build # production build → apps/web/dist
npm run preview # serve the production build
Everything is static output — deploy apps/web/dist anywhere.
The included workflow (.github/workflows/deploy.yml) builds with
BASE_PATH=/<repo>/ and publishes to Pages on every push to main
(enable Settings → Pages → Source: GitHub Actions once). Any other static
host works too: set BASE_PATH to the sub-path you serve from (default /).
npm-workspaces monorepo, strict TypeScript, zero runtime dependencies in the algorithm packages. The pipeline runs in a Web Worker with cooperative cancellation (latest settings win; stale runs abort between stages).
| Package | Role |
|---|---|
@trazor/core | Shared types, settings schema + profiles, Oklab color math, geometry, deterministic PRNG |
@trazor/raster | Resize, denoise (median/bilateral), background flattening, k-means++ quantization (exact & fixed palettes), Otsu/adaptive thresholds, morphology, Zhang-Suen thinning, chamfer distance |
@trazor/trace | The tracer: crack decomposition, Potrace-chain fitting, shared boundary graph (seam-free cutout), centerline extraction, Schneider fitting |
@trazor/svg | Compact SVG serialization (px/mm, evenodd holes, gap-fill strokes) + output analysis |
@trazor/engine | Mode pipelines, staging/progress/cancellation, warnings, worker protocol + client |
@trazor/ml | Background removal, click-to-segment, learned edge pre-pass, and cleanup, on ONNX Runtime Web + model cache |
@trazor/assist | Image statistics → recommended settings & suggested palettes |
apps/web | Vue 3 + Pinia studio UI |
Pipeline: decode → resize → denoise → flatten alpha → (color) Oklab k-means++ → region cleanup → (opt) gradient detection → per-layer Potrace chain (stacked) or shared boundary graph (cutout) → (bw) threshold → despeckle → trace → (centerline) threshold → thin → graph → fit → serialize → analyze → warn.
Every algorithm's source is cited in docs/REFERENCES.md;
package API contracts live in docs/CONTRACTS.md.
npm test # vitest — 176 unit tests across all packages
npm run typecheck # tsc (packages) + vue-tsc (app)
npm run lint # oxlint
npm run fmt # oxfmt
npm run check # all of the above
npm run e2e # real-browser smoke test (builds required; uses system Chromium)
The e2e script drives the built app with Playwright, vectorizes the bundled
samples, saves the SVGs to e2e-artifacts/ and refreshes docs/screenshot.png.
The ML approach behind several of these — shape/primitive fitting, semantic layering, the differentiable refinement pass —
and how a training dataset would be produced (and how determinism is scoped so WebGPU stays allowed) is written up in
docs/ML_STRATEGY.md.
TypeScript
74.2%
Vue
15.0%
JavaScript
7.2%
Python
2.4%
Raster image (PNG, JPEG) to SVG converter, entirely in your browser
45
stars
189
commits
TypeScript
primary language
Sep 4, 2026
updated
Raster → SVG, entirely in your browser. A vectorization studio that turns PNG/JPEG/WebP/GIF/BMP images into clean, editable, cuttable SVG — with no server, no upload, no account. Host it on any static host (GitHub Pages included); your images never leave the machine.

Because the tracing algorithm is the product. Trazor implements a full Potrace-class curve chain (from Peter Selinger's 2003 paper — clean-room, no GPL code) and applies it per color layer, not just to black & white:
On top of that, three things most tracers don't do:
cutout layering the color segmentation's
boundary network is fitted once — every edge shared by two regions is a
single curve reused by both (with junction points pinned exactly). Adjacent
shapes are mathematically identical along their shared border: no hairline
gaps, no overlaps, ever. Ideal for cutting machines, screen printing and
clean editing.stacked (layers extend underneath — crack-proof, great for
illustration) or cutout (exact seam-free partition).pixel —
pixel-perfect rectilinear paths that keep sprite art exact.<linearGradient>/<radialGradient> instead of posterized bands — mesh-free
(geometry unchanged, cutout stays seam-free), fewer shapes, no banding.
Experimental and off by default; enable "Gradient fills" in the palette
settings.<g> sheet per color, mm units),
Laser engrave, Pen plotter (centerline, for line art), Stencil
(island detection warns about pieces that would fall out).<rect>/<circle> detection, and circular-arc A fitting that collapses
near-circular Bézier runs to exact arcs), group-by-color (one <g> layer per color
so cut/print tools separate sheets automatically), tiny-feature warnings below
cuttable size.N) that draws every path's anchor
points, Bézier handles and outlines — color-coded by element kind (traced
paths vs. rect/circle/ellipse primitives, with a legend) so you can see
the traced geometry's complexity at a glance, per-stage timings, palette
swatches, node/path/byte stats, download / copy / data-URI export, dark &
light themes, keyboard shortcuts..json file, and import it back by paste or file — share a
recipe or move it between machines. Everything stays local.npm install
npm run dev # Vite dev server
npm run build # production build → apps/web/dist
npm run preview # serve the production build
Everything is static output — deploy apps/web/dist anywhere.
The included workflow (.github/workflows/deploy.yml) builds with
BASE_PATH=/<repo>/ and publishes to Pages on every push to main
(enable Settings → Pages → Source: GitHub Actions once). Any other static
host works too: set BASE_PATH to the sub-path you serve from (default /).
npm-workspaces monorepo, strict TypeScript, zero runtime dependencies in the algorithm packages. The pipeline runs in a Web Worker with cooperative cancellation (latest settings win; stale runs abort between stages).
| Package | Role |
|---|---|
@trazor/core | Shared types, settings schema + profiles, Oklab color math, geometry, deterministic PRNG |
@trazor/raster | Resize, denoise (median/bilateral), background flattening, k-means++ quantization (exact & fixed palettes), Otsu/adaptive thresholds, morphology, Zhang-Suen thinning, chamfer distance |
@trazor/trace | The tracer: crack decomposition, Potrace-chain fitting, shared boundary graph (seam-free cutout), centerline extraction, Schneider fitting |
@trazor/svg | Compact SVG serialization (px/mm, evenodd holes, gap-fill strokes) + output analysis |
@trazor/engine | Mode pipelines, staging/progress/cancellation, warnings, worker protocol + client |
@trazor/ml | Background removal, click-to-segment, learned edge pre-pass, and cleanup, on ONNX Runtime Web + model cache |
@trazor/assist | Image statistics → recommended settings & suggested palettes |
apps/web | Vue 3 + Pinia studio UI |
Pipeline: decode → resize → denoise → flatten alpha → (color) Oklab k-means++ → region cleanup → (opt) gradient detection → per-layer Potrace chain (stacked) or shared boundary graph (cutout) → (bw) threshold → despeckle → trace → (centerline) threshold → thin → graph → fit → serialize → analyze → warn.
Every algorithm's source is cited in docs/REFERENCES.md;
package API contracts live in docs/CONTRACTS.md.
npm test # vitest — 176 unit tests across all packages
npm run typecheck # tsc (packages) + vue-tsc (app)
npm run lint # oxlint
npm run fmt # oxfmt
npm run check # all of the above
npm run e2e # real-browser smoke test (builds required; uses system Chromium)
The e2e script drives the built app with Playwright, vectorizes the bundled
samples, saves the SVGs to e2e-artifacts/ and refreshes docs/screenshot.png.
The ML approach behind several of these — shape/primitive fitting, semantic layering, the differentiable refinement pass —
and how a training dataset would be produced (and how determinism is scoped so WebGPU stays allowed) is written up in
docs/ML_STRATEGY.md.
TypeScript
74.2%
Vue
15.0%
JavaScript
7.2%
Python
2.4%