svgo — Optimize and Minify SVG Files
Practical guide to svgo — optimize SVG files, strip metadata and shrink file size via the CLI, npx and svgo.config.js.
svgo is the de-facto standard for optimizing SVG files: the Node.js tool strips comments, editor metadata and excess precision, merges paths and often cuts file size in half – usually with no visible loss in quality. Run it globally installed (npm i -g svgo) or straight from npx svgo, optimize single files or whole folders, and control every detail through plugins in an svgo.config.js. One caveat, though: without -o svgo writes in-place and overwrites the original, so keep a backup.
Basic Usage
svgo <input.svg> — Optimize an SVG file in-place (overwrites original).
svgo icon.svgsvgo <input.svg> -o <output.svg> — Optimize and write to a different file.
svgo logo.svg -o logo.min.svgsvgo -i <input.svg> -o <output.svg> — Explicit input/output flags.
svgo -i src/logo.svg -o dist/logo.svgsvgo -f <directory> — Optimize all SVGs in a directory (in-place).
svgo -f icons/svgo -f <input-dir> -o <output-dir> — Optimize directory of SVGs to a separate output directory.
svgo -f src/icons/ -o dist/icons/svgo -s '<svg>...</svg>' — Optimize an SVG string directly.
svgo -s '<svg xmlns="http://www.w3.org/2000/svg"><rect width="100" height="100"/></svg>'cat <input.svg> | svgo -i - -o - — Read from stdin, write to stdout (for piping).
cat icon.svg | svgo -i - -o - > icon.min.svgOutput Options
svgo --pretty <input.svg> -o <output.svg> — Pretty-print the output with indentation.
svgo --pretty logo.svg -o logo.clean.svgsvgo --indent <n> --pretty <input.svg> -o <output.svg> — Set indentation level for pretty-print (default: 4).
svgo --indent 2 --pretty logo.svg -o logo.clean.svgsvgo --final-newline <input.svg> -o <output.svg> — Ensure output ends with a newline character.
svgo --final-newline icon.svg -o icon.min.svgsvgo -r -f <directory> — Recursively optimize SVGs in subdirectories.
svgo -r -f assets/Configuration
svgo --config <config.js> <input.svg> — Use a custom configuration file.
svgo --config svgo.config.js icon.svgsvgo -p <n> <input.svg> — Override the number of fractional digits (precision) across all plugins.
svgo -p 2 icon.svgsvgo -f <directory> --exclude <pattern> — Exclude files matching a regex pattern (use with -f only).
svgo -f icons/ --exclude 'sprite.*\.svg'svgo --datauri <format> <input.svg> — Output the result as a Data URI (base64, enc or unenc).
svgo --datauri base64 icon.svg -o icon.txtsvgo --multipass <input.svg> — Run multiple optimization passes until no further savings.
svgo --multipass complex-graphic.svgsvgo --show-plugins — List all available built-in plugins.
svgo --show-pluginsConfig File (svgo.config.js)
module.exports = { plugins: ['preset-default'] } — Minimal config using the default preset (all default plugins).
// svgo.config.js
module.exports = { plugins: ['preset-default'] }{ name: 'preset-default', params: { overrides: { removeViewBox: false } } } — Use default preset but disable removeViewBox (important for responsive SVGs).
module.exports = { plugins: [{ name: 'preset-default', params: { overrides: { removeViewBox: false } } }] }{ name: 'preset-default', params: { overrides: { cleanupIds: false } } } — Keep IDs intact (needed when referencing SVG elements from CSS/JS).
module.exports = { plugins: [{ name: 'preset-default', params: { overrides: { cleanupIds: false } } }] }{ name: 'removeAttrs', params: { attrs: '(fill|stroke)' } } — Remove specific attributes (e.g., for CSS-controlled icons).
module.exports = { plugins: ['preset-default', { name: 'removeAttrs', params: { attrs: '(fill|stroke)' } }] }{ name: 'addAttributesToSVGElement', params: { attributes: [{ 'aria-hidden': 'true' }] } } — Add attributes to the root SVG element.
module.exports = { plugins: ['preset-default', { name: 'addAttributesToSVGElement', params: { attributes: [{ 'aria-hidden': 'true' }] } }] }{ name: 'sortAttrs' } — Sort element attributes for consistent output.
module.exports = { plugins: ['preset-default', 'sortAttrs'] }{ name: 'removeDimensions' } — Remove width/height and add viewBox if missing (for responsive SVGs).
module.exports = { plugins: ['preset-default', 'removeDimensions'] }Key Default Plugins
removeDoctype — Remove DOCTYPE declaration.
Removes: <!DOCTYPE svg PUBLIC ...>removeXMLProcInst — Remove XML processing instructions.
Removes: <?xml version="1.0" encoding="UTF-8"?>removeComments — Remove all XML comments.
Removes: <!-- Created with Illustrator -->removeMetadata — Remove
Removes: <metadata>...</metadata>removeEditorsNSData — Remove editor namespace data (Inkscape, Sketch, Illustrator).
Removes: inkscape:*, sodipodi:*, sketch:* attributescleanupIds — Minify and deduplicate element IDs.
Renames: id="SVGID_1_" → id="a"removeUselessDefs — Remove
Removes unused gradient, filter, or symbol definitionscollapseGroups — Collapse useless
Removes: <g><rect.../></g> → <rect.../>mergePaths — Merge multiple
Combines adjacent paths with same attributesconvertPathData — Optimize path data: remove redundant commands, round values.
M10.123 20.456 → M10.1 20.5Common Patterns
svgo -f icons/ -o icons/ --config svgo.config.js — Optimize all icons with a project-specific config.
svgo -f src/icons/ -o dist/icons/ --config svgo.config.jsfind . -name '*.svg' -exec svgo {} \; — Recursively optimize all SVGs in subdirectories.
find assets/ -name '*.svg' -exec svgo --multipass {} \;svgo -f <directory> --config icons.config.js — Safe optimization for icon systems (preserve viewBox and IDs via config).
svgo -f components/icons/ --config icons.config.jssvgo --multipass --pretty --indent 2 -o <output.svg> <input.svg> — Maximum optimization with readable output (for source-controlled SVGs).
svgo --multipass --pretty --indent 2 -o logo.svg raw-logo.svgnpx svgo <input.svg> -o <output.svg> — Run without global installation via npx.
npx svgo logo.svg -o logo.min.svgnpx svgo@latest -f <directory> — Run the latest version without installing.
npx svgo@latest -f icons/ Conclusion
svgo belongs in every frontend build: a single run strips editor cruft, trims path data and saves real bytes – for everyday work svgo file.svg -o file.min.svg, the folder mode -f and an svgo.config.js are all you need. Be aware of the pitfalls, though: without -o svgo works in-place and overwrites the original, so back it up first. Aggressive defaults can break SVGs – removeViewBox breaks the scaling of responsive graphics (usually disable it), too low a floatPrecision causes visible distortion, and cleanupIds can break references from animations, <use> or external CSS/JS. Drive those plugins deliberately through the config. Note: the old --enable/--disable CLI flags from svgo 1.x were removed in version 2/3 – plugins are now configured exclusively via svgo.config.js.
Further Reading
- svgo on GitHub – source code, plugin reference and full configuration documentation
- MDN: SVG – reference for the SVG format and its elements