SVG in. Editable draw.io out.
svg2drawio converts an SVG into a .drawio file whose cells are
native draw.io shapes — real rectangles, ellipses, edges with draggable endpoints and
text you can retype. Not an embedded picture: a diagram you can keep working on.
Install
A single static binary. macOS and Linux, Intel and Apple Silicon.
# Homebrew
brew tap bcollard/svg2drawio
brew install --cask svg2drawio
# or with a Go toolchain
go install github.com/bcollard/svg2drawio/cmd/svg2drawio@latest
Usage
The bare command converts; subcommands cover the rest.
# One file → diagram.drawio next to it
svg2drawio diagram.svg
# A tree of icons into one output directory
svg2drawio -o out/ icons/
# Several SVGs as pages of a single file
svg2drawio -o all.drawio a.svg b.svg c.svg
# Straight into draw.io's Extras → Edit Diagram box
svg2drawio -o - diagram.svg | pbcopy
Why not just import the SVG?
draw.io can place an SVG on the canvas, but it stays one opaque picture.
Real cells, not a picture
Each shape is its own mxCell with its own fill, stroke and geometry. Select it, move it, recolour it.
Connectors stay connectors
Lines, polylines and straight paths become edges with draggable endpoints and waypoints; SVG markers become arrowheads.
Text stays text
Font family, size, weight, colour and alignment carry over into editable labels — no re-typing, no bitmap text.
Curves become native shapes
Arbitrary paths are emitted as inline stencils, the same object draw.io writes for its own custom shapes.
CSS is resolved first
Class-driven SVGs from design tools and LLMs work: <style> rules are applied through the cascade before conversion.
One binary, no runtime
Pure Go, no dependencies, MIT licensed. Runs in CI as easily as on a laptop.
What converts
The mapping from SVG to draw.io, element by element.
| SVG | draw.io |
|---|---|
rect (with rx/ry) | native rectangle, rounded with an absolute arc size |
circle, ellipse | native ellipse |
line, open polyline, straight path | edge with floating endpoints and waypoints |
polygon, curved or filled path | vertex with an inline stencil |
text, tspan | text cell with font family, size, colour, weight and alignment |
image | shape=image, data URIs rewritten the way draw.io stores them |
g | draw.io group, children rebased on the group origin |
use, symbol | expanded before conversion |
| gradients | fillColor + gradientColor + gradientDirection |
marker-start, marker-end | block arrowheads on the edge |
transform | baked into coordinates; rotation survives as rotation= |
viewBox, width, height | page size and user-unit scale |
For AI coding agents
svg2drawio ships an Agent Skill, so tools like Claude Code know when and how to use it without being told each session.
svg2drawio skill install # → ~/.claude/skills/svg2drawio/SKILL.md
svg2drawio skill install --print # write it anywhere you like
Questions
How are curved shapes handled?
Anything draw.io has no native shape for — a curved or filled path, a polygon — is written as an inline stencil, the same object draw.io produces for its own custom shapes. It stays a real cell: selectable, resizable, and recolourable from the format panel.
What does not survive the conversion?
clipPath, mask, filter and pattern fills are
ignored, fill-rule="evenodd" has no mxGraph equivalent, and text on a
path is placed at its anchor point. Text box sizes are estimated, because draw.io
lays text out itself — a long label may need a nudge after import.
Does it phone home?
No. It reads files and writes files. No network access, no telemetry, nothing uploaded to a conversion service.
Can I check the result into git?
Yes — the output is plain XML with stable ids, so diffs are readable. Keep the source SVG next to it; the conversion is one-way.