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.svg

svgo <input.svg> -o <output.svg> — Optimize and write to a different file.

svgo logo.svg -o logo.min.svg

svgo -i <input.svg> -o <output.svg> — Explicit input/output flags.

svgo -i src/logo.svg -o dist/logo.svg

svgo -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.svg

Output Options

svgo --pretty <input.svg> -o <output.svg> — Pretty-print the output with indentation.

svgo --pretty logo.svg -o logo.clean.svg

svgo --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.svg

svgo --final-newline <input.svg> -o <output.svg> — Ensure output ends with a newline character.

svgo --final-newline icon.svg -o icon.min.svg

svgo -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.svg

svgo -p <n> <input.svg> — Override the number of fractional digits (precision) across all plugins.

svgo -p 2 icon.svg

svgo -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.txt

svgo --multipass <input.svg> — Run multiple optimization passes until no further savings.

svgo --multipass complex-graphic.svg

svgo --show-plugins — List all available built-in plugins.

svgo --show-plugins

Config 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 elements.

Removes: <metadata>...</metadata>

removeEditorsNSData — Remove editor namespace data (Inkscape, Sketch, Illustrator).

Removes: inkscape:*, sodipodi:*, sketch:* attributes

cleanupIds — Minify and deduplicate element IDs.

Renames: id="SVGID_1_" id="a"

removeUselessDefs — Remove with no references.

Removes unused gradient, filter, or symbol definitions

collapseGroups — Collapse useless wrapper groups.

Removes: <g><rect.../></g> <rect.../>

mergePaths — Merge multiple elements into one where possible.

Combines adjacent paths with same attributes

convertPathData — Optimize path data: remove redundant commands, round values.

M10.123 20.456 M10.1 20.5

Common 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.js

find . -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.js

svgo --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.svg

npx svgo <input.svg> -o <output.svg> — Run without global installation via npx.

npx svgo logo.svg -o logo.min.svg

npx 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
  • convert – convert raster and vector images (ImageMagick), including SVG rasterization
  • pngquant – lossy compression of PNG files
  • optipng – lossless optimization of PNG files