Split a single SVG into multiple standalone, cropped SVG files.
📖 No command line needed — see the user guide: English · Español
SVG Parts supports two complementary splitting strategies:
- 🌳 XML tree (layers, groups, shapes...)
- 🎨 Fill color
Typical use cases:
- Laser cutting
- Cricut / vinyl cutting
- EVA foam templates
- Multi-color printing
- Extracting individual assets from complex SVGs
The same splitting engine powers four different frontends:
- 🧩 Inkscape extension
- 💻 Command-line tool
- 🐍 Python library
- 🌐 Web application (Pyodide)
The core splitting algorithm is shared across every frontend. Differences in the exported output are limited to backend-specific capabilities. Both supported SVG engines are tested against the same input documents to ensure consistent behaviour and to catch regressions.
There's no PyPI package yet. core/ imports itself by absolute name
(from core.backend import ...), so the repo root has to be on sys.path
— either run from it, or point at it:
import sys
sys.path.insert(0, "/path/to/svgparts") # not needed if that's your cwd
from core.api import export_parts
result = export_parts(
svg_text,
split_mode="fill-color"
)
for part in result["parts"]:
print(part["name"])export_parts() is string in, strings out — it never touches the
filesystem, which is what lets the same call run under Pyodide.
pip install svgelements
python3 svgparts.py drawing.svg \
-o output \
--split-mode=fill-colorTree mode:
python3 svgparts.py drawing.svg \
-o output \
--split-mode=tree \
--only-leaves \
--depth=3Arguments (--help output; the engines listed under --engine are
whichever ones are importable where you run it):
positional arguments:
svg_file input SVG file
options:
-h, --help show this help message and exit
--version show program's version number and exit
-o OUTPUT_DIR, --output-dir OUTPUT_DIR
output directory (default: parts)
--engine {inkex,svgelements}
SVG engine to use (default: auto-detect; available here: inkex, svgelements)
--split-mode {tree,fill-color}
split by XML tree structure or by fill color (default: tree)
--depth DEPTH max tree depth, -1 = unlimited (default: -1)
--only-leaves keep only the deepest checked type per branch, not every matching layer/group/shape along the way (tree mode)
--no-layers don't export layers (tree mode)
--no-groups don't export groups (tree mode)
--shapes also export individual shapes (tree mode)
--margin MARGIN crop margin in mm (default: 0.5)
--full-fidelity tree AND fill-color mode: preserve the full document (defs, gradients, original group structure) instead of flattening to
plain <path> elements. Only works with --engine=inkex; ignored (with a warning) otherwise. Off by default because in tree
mode with --only-leaves this means one full-document deep-copy per exported shape -- can get slow on complex documents.
--preserve-doc-size keep every exported part at the ORIGINAL document's size and viewBox instead of cropping it to its own bounding box
(--margin then has nothing to apply to). Useful when the parts have to line up with each other afterwards, since they all
keep one coordinate system. Only affects --full-fidelity output; ignored, with a warning, otherwise, since flattened parts
are built from scratch around their own bounding box.
--output-format {svg,dxf}
output file format (default: svg). 'dxf' needs the optional ezdxf + svgelements + numpy packages (pip install ezdxf
svgelements numpy) and always flattens (DXF has no defs/gradients/group-structure to preserve).
Copy
svgparts.inxsvgparts_inkex.pycore/backends/(onlyinkex_backend.pyis ever used here)assets/icon.svg(referenced by<icon>in the.inx)
into your User Extensions folder and restart Inkscape.
Or run ./package_for_inkscape.sh and unzip the result there — it builds
exactly that set, and nothing else.
The extension appears under:
Extensions → Export → SVG Parts
If objects are selected, only the selection is exported.
A browser version is available at
https://svgparts.kraft-steam.com/
The web application runs entirely in the browser using Pyodide, reusing the same Python code as the CLI and library. Since Inkscape's inkex library is difficult to run in a browser, the web frontend transparently uses the svgelements backend.
core/ engine-agnostic logic (no inkex/svgelements imports)
backend.py SvgBackend ABC + auto-detecting factory
exporter.py tree-mode / fill-color-mode splitting, SVG serialization
api.py in-memory API: string in, strings out (no filesystem)
dxf_writer.py optional DXF output (needs ezdxf+svgelements+numpy;
guarded import, everything else works without it)
backends/
inkex_backend.py adapter over inkex (Inkscape's own library)
svgelements_backend.py adapter over svgelements (pure Python, no C deps)
svgparts.py standalone CLI -- no inkex dependency
svgparts_inkex.py Inkscape extension entry point (see svgparts.inx)
svgparts.inx Inkscape extension descriptor
The project follows a simple dependency inversion design.
core/ contains all splitting logic and never imports inkex or svgelements.
Instead, both engines implement the same SvgBackend interface.
---
config:
theme: 'base'
themeVariables:
primaryColor: '#FEFEFE'
primaryTextColor: '#555555'
primaryBorderColor: '#AAAAAA'
lineColor: '#555555'
secondaryColor: '#666666'
tertiaryColor: '#AAAAAA'
---
flowchart TB
subgraph Frontends
API[Python API]
CLI[CLI]
INK[Inkscape]
PYODIDE[Pyodide]
end
CORE["<b>core</b><br/>engine-agnostic splitting logic"]
BACKEND["<b>SvgBackend</b><br/>abstract contract + auto-detecting factory"]
subgraph Backends
INKEX[Inkex backend]
SVGEL[svgelements backend]
end
API --> CORE
CLI --> CORE
INK --> CORE
PYODIDE --> CORE
CORE --> BACKEND
BACKEND --> INKEX
BACKEND --> SVGEL
This means the splitting algorithm exists only once while supporting multiple SVG engines.
Adding a new backend requires implementing the SvgBackend interface without changing the core algorithm.
- Split by XML tree
- Split by fill color
- Crop every exported SVG (opt out with
--preserve-doc-size) - Flatten inherited styles
- Recover referenced gradients, clip paths and patterns
- Optional full-fidelity export (
inkex) - Optional DXF export
- Selection-aware inside Inkscape
- Pure in-memory Python API
- Runs inside Pyodide
GPL-3.0-or-later — see LICENSE for the full text, and the header of each source file.