svag

Crates.iosvag
lib.rssvag
version0.1.2
created_at2025-12-01 23:31:03.328536+00
updated_at2025-12-02 02:38:07.584946+00
descriptionAn SVG minifier
homepagehttps://github.com/bearcove/svag
repositoryhttps://github.com/bearcove/svag
max_upload_size
id1960849
size173,252
Amos Wenger (fasterthanlime)

documentation

https://docs.rs/svag

README

svag

MIT + Apache 2.0 crates.io docs.rs

An SVG minifier.

Features

  • Remove XML declarations, DOCTYPE, comments
  • Remove metadata, title, desc elements
  • Remove Inkscape/Sodipodi namespaces and elements
  • Remove unused namespace declarations
  • Collapse unnecessary groups
  • Remove hidden and empty elements
  • Minify path data (reduce precision, implicit commands)
  • Minify colors (#ff0000red, #ffffff#fff)
  • Remove default attribute values
  • Minify inline styles
  • Sort attributes for better gzip

Usage

As a library

use svag::minify;

let svg = r#"<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
    <!-- A red square -->
    <rect x="10" y="10" width="80" height="80" fill="#ff0000" fill-opacity="1"/>
</svg>"#;

let minified = minify(svg).unwrap();
// <svg xmlns="http://www.w3.org/2000/svg" height="100" width="100"><rect fill="red" height="80" width="80" x="10" y="10"/></svg>

As a CLI

# From stdin
echo '<svg>...</svg>' | svag

# From file
svag input.svg -o output.svg

# With stats
svag input.svg --stats
# 1961 -> 602 bytes (69.3% smaller)

With custom options

use svag::{minify_with_options, Options};

let options = Options {
    precision: 1,           // decimal places for coordinates
    remove_comments: true,
    minify_paths: true,
    minify_colors: true,
    ..Options::default()
};

let minified = minify_with_options(svg, &options).unwrap();

Installation

cargo add svag

Or for the CLI:

cargo install svag

Benchmarks

Test corpus: 4858 SVG files (1042.5 MB total)

svag svgo
Output size 729.0 MB (-30.1%) 412.2 MB (-60.5%)
Bytes saved 313.6 MB 630.3 MB
Processing time 514.1ms 26.92s
Methodology

The test corpus includes SVGs from the W3C SVG 1.1 Test Suite, KDE Oxygen Icons, and Wikimedia Commons. Duplicates are removed by content hash.

Both tools run in parallel using all available CPU cores:

Timing is wall-clock time for processing all files. This avoids penalizing svgo for Node.js startup overhead.

To regenerate: npm install svgo && cargo xtask fetch-corpus && cargo xtask readme

FAQ

Why "svag"?

Because it's swag.

Is it production-ready?

No, but the tests make me reasonably sure it won't mess anything up.

Roadmap

  • More optimization passes (close the gap with svgo's compression)

Inspired by

  • svgo - The OG SVG optimizer
  • oxvg - Rust SVGO port

License

MIT OR Apache-2.0

Commit count: 0

cargo fmt