Skip to main content

Pure-Python SVG path editing, optimization, matrix geometry, measurement, sanitization, viewport editing, validation, tracing, and centerline reconstruction.

Project description

svgo

svgo is a pure-Python SVG toolchain for path editing, SVG optimization, PNG icon tracing, centerline reconstruction, geometry conversion, matrix transforms, measurement, sanitization, viewBox/viewport edits, and SVG inspection. It ships as an importable Python package and as a single svgo command-line program.

The package has no required runtime dependencies. If numpy is installed, some centerline distance-transform work can use accelerated array operations; otherwise the standard-library fallback is used.

Features

  • Edit SVG path data with ordered operations: translate, scale, affine matrix, rotate, relative/absolute serialization, subpath reversal, origin changes, and path optimization profiles.
  • Optimize whole SVG files with Python implementations of common SVGO-style cleanup and minification operations.
  • Trace simple PNG icons into filled SVG paths without shelling out to external tracing tools.
  • Convert filled stroke outlines into approximate stroked centerlines.
  • Convert SVG geometry primitives to path data and create common affine matrices from Python.
  • Measure path/SVG length, bounds, and point-at-length coordinates.
  • Set, fit, and resize root SVG viewBox, width, and height values.
  • Validate SVG XML, inspect dimensions/element counts/fonts, and run structural conversions such as shape-to-path conversion, plain cleanup, CSS style inlining, sanitization, and transform flattening.
  • Use the same functionality from Python APIs or from the documented CLI.

Installation

From PyPI, once published:

python -m pip install svgo

From this repository:

python -m pip install .

For local development with uv:

uv sync
uv run svgo --help

CLI

The CLI entry point is svgo. It is organized into short subcommands, each with a one-letter alias:

svgo path   --path "<d>" [--op OP ...] [--svgo]                         # alias: p
svgo path   --input icon.svg --output icon.out.svg --select all|N|N,N --op OP
svgo opt    --input icon.svg --output icon.min.svg [optimization options] # alias: o
svgo trace  --input icon.png --output traced.svg [trace options]          # alias: t
svgo trace2 --input icon.png --output traced.svg [VTracer options]        # alias: t2
svgo center --input outline.svg --output stroke.svg [centerline options]  # alias: c
svgo info   --input icon.svg                                             # alias: i
svgo validate --input icon.svg [--strict]                                # alias: v
svgo measure --input icon.svg                                            # alias: m
svgo sanitize --input icon.svg --output safe.svg                         # alias: s
svgo viewbox --input icon.svg --fit-content --output fitted.svg          # alias: b
svgo convert --input icon.svg --output converted.svg [conversion options] # alias: x
svgo plugins                                                             # alias: l

Every command supports --help:

svgo --help
svgo path --help
svgo opt --help
svgo trace --help
svgo trace2 --help
svgo center --help
svgo info --help
svgo validate --help
svgo measure --help
svgo sanitize --help
svgo viewbox --help
svgo convert --help

Path Editing

Path operations are applied in order with repeated --op flags:

svgo path --path "M10 10h5v5z" --op "matrix(-1,0,0,1,30,0)" --minify
svgo p --input icon.svg --output edited.svg --select 0,2 --op translate:2,-1 --op optimize:safe

Supported operations:

  • translate:dx,dy
  • scale:kx,ky
  • matrix:a,b,c,d,e,f or matrix(a,b,c,d,e,f)
  • rotate:ox,oy,degrees
  • relative
  • absolute
  • reverse or reverse:itemIndex
  • origin:itemIndex or origin:itemIndex:subpath
  • cubics, cubic, to-cubics, or toCubics
  • optimize:safe, optimize:size, optimize:closed, optimize:all
  • optimize:remove-useless,use-shorthands,use-hv,use-relative-absolute,use-reverse,use-close-path,remove-orphan-dots

The affine matrix uses SVG convention:

x' = a*x + c*y + e
y' = b*x + d*y + f

Arcs are converted to cubic Beziers during arbitrary affine transforms so reflections, rotations, scales, and skews stay fully Python based.

SVG Optimization

svgo opt optimizes SVG documents. svgo path --svgo applies the same SVG optimizer after path edits:

svgo opt --input icon.svg --output icon.min.svg --svgo-multipass --svgo-precision 3
svgo o --input icon.svg --svgo-disable cleanupIds --svgo-plugin removeDimensions
svgo opt --input icon.svg --svgo-preset none --svgo-plugin convertShapeToPath --svgo-plugin sortAttrs
svgo l

Supported options include:

  • --svgo-preset default|none
  • --svgo-plugin NAME[:JSON]
  • --svgo-disable NAME
  • --svgo-precision N
  • --svgo-multipass
  • --svgo-pretty
  • --svgo-indent N
  • --svgo-eol lf|crlf
  • --svgo-final-newline
  • --svgo-datauri base64|enc|unenc
  • --svgo-config FILE

--svgo-config accepts JSON files and Python-readable TOML files. JavaScript SVGO configs are intentionally rejected because this implementation does not execute Node.js.

PNG Tracing

PNG tracing has two modes. trace is the dependency-free pixel tracer: it decodes non-interlaced 8-bit PNGs with the standard library, groups visible pixels, traces connected-component boundaries, and writes filled SVG paths.

svgo trace --input icon.png --output traced.svg --mode palette --curve-mode pixel --max-colors 8 --quantize 24 --min-area 8

Modes:

  • palette: group pixels into dominant quantized colors.
  • alpha: trace a single alpha mask using the most common visible color.
  • exact: keep exact quantized color buckets.

Useful options:

  • --curve-mode pixel|exact: keep exact per-pixel boundaries. This preserves the original tracer behavior.
  • --drop-white
  • --alpha-threshold N
  • --white-threshold N
  • --quantize N
  • --max-colors N
  • --min-area N
  • --scale N
  • --decimals N
  • --title TEXT

For higher-quality curve fitting, use trace2/t2. It calls the real VTracer Python package when installed, or a vtracer CLI on PATH. The default values match VTracer's web-app defaults and the FreeConvert-style controls:

svgo trace2 --input icon.png --output traced.svg
uv run --with vtracer svgo trace2 --input icon.png --output traced.svg
svgo t2 --input icon.png --output traced.svg --curve-mode spline --filter-speckle 4 --color-precision 6 --gradient-step 16

VTracer options:

  • --color-mode color|binary
  • --hierarchical stacked|cutout or --clustering stacked|cutout
  • --color-precision N
  • --gradient-step N
  • --filter-speckle N
  • --curve-mode pixel|polygon|spline
  • --corner-threshold N
  • --segment-length N
  • --max-iterations N
  • --splice-threshold N
  • --path-precision N

Centerline Reconstruction

Centerline reconstruction converts filled stroke outlines into approximate stroked paths by flattening path data, rasterizing with even-odd fill, skeletonizing with Zhang-Suen thinning, estimating stroke width, and tracing the skeleton.

svgo center --path "M0 0L100 0L100 20L0 20Z" --emit path
svgo c --input traced.svg --output centerline.svg --svg-paths all --mode all --simplify 4

Important options:

  • --emit path|svg|d
  • --mode longest|all
  • --scale N
  • --max-size N
  • --curve-samples N
  • --simplify N
  • --min-length N
  • --stroke-width auto|N
  • --linecap VALUE
  • --linejoin VALUE
  • --polyline
  • --svg-paths first|all
  • --keep-failed

Centerline output is intentionally approximate. For production icon work, render and inspect the result before final minification.

Inspection And Conversion

svgo info prints structured JSON metadata:

svgo info --input icon.svg
svgo i --input icon.svg --compact

svgo validate checks SVG XML and reports structural issues. Warnings do not make the command fail unless --strict is used:

svgo validate --input icon.svg
svgo v --input icon.svg --strict --json

svgo measure reports path/SVG length and axis-aligned bounds. It accepts raw path data, SVG files, or text files containing path data:

svgo measure --path "M0 0H10V10H0Z" --decimals 3
svgo m --input icon.svg --compact
svgo m --path "M0 0H10V10" --at 15

svgo sanitize removes active or unsafe content while keeping normal static SVG geometry:

svgo sanitize --input icon.svg --output icon.safe.svg
svgo s --input icon.svg --remove-external-refs --remove-styles

svgo viewbox edits root viewport metadata:

svgo viewbox --input icon.svg --set "0 0 24 24" --remove-dimensions
svgo b --input icon.svg --fit-content --padding 1 --precision 2
svgo b --input icon.svg --width 48 --height 48

svgo convert runs pure-Python structural conversions. With no conversion flags it converts basic shapes to paths:

svgo convert --input shapes.svg --output paths.svg
svgo x --input drawing.svg --output plain.svg --to-plain
svgo x --input transformed.svg --output flat.svg --shapes-to-paths --flatten-transforms
svgo x --input styled.svg --output inline.svg --inline-styles
svgo x --input source.svg --output converted.svg --all --precision 3

Conversion options:

  • --to-plain: remove common editor metadata and editor-specific attributes.
  • --shapes-to-paths: convert rect, circle, ellipse, line, polyline, and polygon to path.
  • --flatten-transforms: bake supported transforms into path coordinates.
  • --flatten-groups: collapse empty unstyled groups.
  • --inline-styles: inline simple style-element rules into presentation attributes.
  • --sanitize: remove scripts, event handlers, and unsafe links before conversion.
  • --all: enable every conversion pass.
  • --precision N: control generated numeric precision.

Python API

from svgo import (
    PathData,
    centerline_path_data,
    circle_to_path,
    get_svg_info,
    fit_viewbox_svg,
    inline_styles_svg,
    optimize_svg,
    path_metrics,
    path_to_cubics,
    rect_to_path,
    resize_svg,
    sanitize_svg,
    set_viewbox_svg,
    trace_png,
    transform_2d,
    translate_2d,
    validate_svg,
)

path = PathData.parse("M0 0L10 0L10 10Z")
path.transform((1, 0, 0, 1, 2, -1))
path.optimize("safe")
print(path.to_string(decimals=3, minify=True))

svg = optimize_svg("<svg><rect width='10' height='10'/></svg>")
shape = rect_to_path(0, 0, 24, 12, rx=2, decimals=3, minify=True)
cubic = path_to_cubics("M0 0L10 0Q15 0 15 5", decimals=3, minify=True)
x, y = transform_2d(translate_2d(10, 5), 1, 2)
report = validate_svg("<svg viewBox='0 0 10 10'/>")
metrics = path_metrics("M0 0H10V10H0Z", decimals=3)
safe_svg = sanitize_svg("<svg onload='x()'><path d='M0 0H1'/></svg>")
fitted_svg = fit_viewbox_svg("<svg><path d='M2 3H6V7H2Z'/></svg>")

The lower-level modules are:

  • svgo.pathdata
  • svgo.geometry
  • svgo.measure
  • svgo.viewport
  • svgo.inspect_svg
  • svgo.svg_optimize
  • svgo.raster_trace
  • svgo.centerline

Reference Tools

These projects are useful reference points for SVG feature coverage, command shape, and API expectations:

  • SVGO: Node.js SVG optimizer and plugin ecosystem.
  • Scour: Python SVG optimizer and cleaner.
  • svgpathtools: Python path, Bezier, geometry, length, and bounds utilities.
  • svg.path: Python SVG path parser and path object model.
  • svg-matrix-python: Python wrapper around SVG matrix conversion and validation workflows.
  • Yqnn/svg-path-editor: SVG path editing UI and path operation reference implementation.
  • svg-path-commander: TypeScript path parsing, normalization, geometry, and transformation tools.
  • Iconify Tools: TypeScript SVG import, validation, cleanup, and export tooling.
  • resvg/usvg: Rust SVG rendering and static SVG simplification/reference implementation.
  • VTracer: Rust raster-to-vector tracing tool.

Development

This repository uses uv's native uv_build backend and has no required runtime dependencies.

uv run python -m unittest discover -s tests
uv build

Publishing

PyPI publishing is handled by GitHub Actions Trusted Publishing through .github/workflows/publish.yml. The PyPI pending publisher must match this repository, the publish.yml workflow filename, and the pypi environment.

To publish a release, update project.version, commit the change, and push a matching tag:

git tag v0.1.0
git push origin v0.1.0

The workflow verifies that the pushed tag equals v{project.version}, runs the test suite, builds the wheel and source distribution with uv, then publishes to PyPI with Trusted Publishing.

The package targets Python 3.11 and newer.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

svgo-0.1.0.tar.gz (52.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

svgo-0.1.0-py3-none-any.whl (57.8 kB view details)

Uploaded Python 3

File details

Details for the file svgo-0.1.0.tar.gz.

File metadata

  • Download URL: svgo-0.1.0.tar.gz
  • Upload date:
  • Size: 52.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for svgo-0.1.0.tar.gz
Algorithm Hash digest
SHA256 62bff621f4dc0b01a2a04176fc8eb3bf96cc2496f13125bd1d7b1ebccc07c6f7
MD5 dceb002b73a8dc972cc723a956f3fe1e
BLAKE2b-256 b888bb576dd3973e293f9d0c8e792c75d801de69d5a7eb8744ee84a96d32432e

See more details on using hashes here.

File details

Details for the file svgo-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: svgo-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 57.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for svgo-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f8e8ace255abad13cc4a727ae7b943f32c9ff95da63d5199b31028700ea0bfd5
MD5 7c5dbfda369682a174f6a4e796bd67b5
BLAKE2b-256 bd127bd4ed4ee1ede85018f51dba030fc76ec9d5ba2b667a6862c0acf4bf0226

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page