svgtidy is a high-performance SVG optimizer written in Rust.
It removes redundant information from SVG files (like comments, metadata, and hidden elements) and creates a minimized, cleaner version without affecting rendering.
Compared to SVGO, svgtidy is fast—up to 100x faster for single icons and 50x faster for complex files.
- Blazing Fast: Built with Rust,
xmlparserandrayon. - Batch Processing: Parallel directory scanning and optimization.
- AST-based: Robust DOM-like mutations.
- Configurable: Toggle plugins, set precision, and precision formatting.
- Cross-Platform: Runs on CLI, Node.js, and in the browser (WASM).
Use svgtidy directly in your JavaScript/TypeScript projects.
npm install svgtidyUsage:
import { optimize } from 'svgtidy';
const svg = '<svg>...</svg>';
const optimized = optimize(svg);
console.log(optimized);Install the binary tool using Rust's cargo:
# Install from crates.io (Recommended)
cargo install svgtidy
# Or build from source
git clone https://github.com/honkinglin/svgtidy.git
cd svgtidy
cargo install --path .Usage:
# Optimize a single file
svgtidy input.svg -o output.svg
# Optimize a directory (recursive)
svgtidy icons/ -o dist/
# Set precision and disable specific plugins
svgtidy input.svg -o output.svg -p 5 --disable removeTitleInstall the dedicated Vite plugin:
npm install vite-plugin-svgtidyUsage (vite.config.js):
import svgtidy from 'vite-plugin-svgtidy';
export default {
plugins: [svgtidy()]
}Install the Webpack loader:
npm install svgtidy-loaderUsage (webpack.config.js):
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
use: [
{ loader: 'svgtidy-loader' }
]
}
]
}
}Usage: svgtidy [OPTIONS] <INPUT>
Arguments:
<INPUT> Input file or directory
Options:
-o, --output <OUTPUT> Output file or directory
-p, --precision <PRECISION> Set numeric precision [default: 3]
--enable <ENABLE> Enable specific plugins (comma-separated)
--disable <DISABLE> Disable specific plugins (comma-separated)
--pretty Pretty print output
-h, --help Print help
svgtidy enables these plugins by default to ensure maximum reduction:
| Plugin Name | Description |
|---|---|
removeDoctype |
Removes <!DOCTYPE> declaration. |
removeXMLProcInst |
Removes <?xml ... ?> instructions. |
removeComments |
Removes comments. |
removeMetadata |
Removes <metadata> elements. |
removeTitle |
Removes <title> elements. |
removeDesc |
Removes <desc> elements. |
removeEditorsNSData |
Removes editor namespaced attributes (Inkscape, etc.). |
cleanupAttrs |
Trims attribute whitespace. |
mergePaths |
Merges adjacent paths with same attributes. |
convertShapeToPath |
Converts basic shapes (rect, circle) to path. |
convertPathData |
Optimizes path commands (relative, precision). |
convertTransform |
Collapses multiple transforms into one. |
removeHiddenElems |
Removes hidden elements (display="none"). |
removeEmptyText |
Removes empty text nodes. |
convertColors |
Converts colors (rgb to hex, etc.). |
collapseGroups |
Removes redundant <g> tags. |
moveGroupAttrsToElems |
Moves attributes from groups to elements. |
moveElemsAttrsToGroup |
Moves common attributes from elements to groups. |
(And more...)
| Scenario | Input Size | svgtidy Time | vs SVGO (Node) |
|---|---|---|---|
| Simple Icon | ~0.5 KB | ~16 µs | ~100x Faster |
| Complex SVG | ~30 KB | ~1 ms | ~50x Faster |
To build the WASM package for web usage (NPM):
wasm-pack build --target bundler --out-dir npm/svgtidy-wasm- Rust:
cargo test - JS/WASM:
cd npm && npm run test:suite
Contributions are welcome!
- Fork the repository.
- Create a feature branch.
- Submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.