SVGO: Optimize the Icon File After the Drawing Is Finished
SVGO is a Node.js library and command-line application for optimizing SVG files. The project describes itself that way in its README, and the docs live at the documentation site. This page is how to use that tool on an icon set without letting it redraw your symbols. It is not a promise about file-size rankings, and it is not a claim that every default plugin is safe for every file.
Draw the icon first. The notes on icon grid systems and optimizing icons for web cover the canvas and the page. SVGO comes after both, on a file you can still diff.
What SVGO is willing to remove
The README’s “Why?” section says SVG files exported from vector editors usually contain redundant information: editor metadata, comments, hidden elements, default or suboptimal values, and other stuff that can be removed or converted without impacting rendering. That is the job. It is not a design tool. If a plugin changes a path so the icon looks different at the size you ship, that plugin is wrong for this set even if the byte count dropped.
Install it the way the README shows, globally or inside the project, with npm, yarn, or pnpm. The global form in the README is npm install -g svgo. Drop the global flag when the project should pin the version. A global install that differs from the version in the repo is how two people “optimize” the same file into two results.
The command line in the README processes single files with svgo one.svg two.svg -o one.min.svg two.min.svg, and a directory with svgo -rf plus an output directory. Read svgo --help before you add flags you found in a comment. This article will not invent flags the README does not list.
How to run SVGO on a set
Keep the source SVG and the optimized SVG as separate files until you have looked at both. Optimizing in place is how you lose the editor file the day a plugin eats a clip path. Write the optimized file to an output directory, open it next to the source at the size the interface uses, and only then replace the shipped file.
Run it on one icon before you run it on the folder. A folder run is the same plugins on every file. One icon that uses a filter, a mask, or an id referenced from CSS will tell you whether the default preset is acceptable. If that icon breaks, do not “fix” it by skipping the tool. Change the config, which the README explains next.
SVGO has a plugin architecture. The README points at the plugins documentation and the default preset. It reads configuration from svgo.config.mjs or from --config. The sample config in the README sets multipass, optional data URI output, pretty-print options, and a plugins list that can include preset-default plus named plugins such as prefixIds. Use a config file in the repo. A command you typed once will not be there for the next export.
Change the default preset instead of starting from nothing
The README says you can tweak the default preset instead of configuring SVGO from scratch. Its example disables cleanupIds and changes inlineStyles by passing overrides inside preset-default. That is the pattern to copy: turn off the plugin that hurt a file, and leave the rest of the preset. Building a private list of plugins from memory will omit ones you needed and include ones you did not mean to run.
Ids are a common reason to override. If a sprite or a stylesheet refers to an id inside the SVG, a plugin that rewrites ids will break the reference. The README shows cleanupIds: false as the example of disabling a default plugin, and prefixIds as a plugin you enable when you want ids prefixed. Read the preset page for the list and the order. Do not assume the example is the full default set.
Multipass, in the README’s sample, is a boolean. The optimize API example sets multipass: true and says the other config fields are available there too. Multipass means the tool can run more than one pass. It does not mean the result is safer. Compare the picture after a multipass run the same way you compare a single pass.
The API in the README is optimize from the svgo package. You pass the SVG string and a config object. path is marked recommended. The optimized markup comes back on result.data. There is also loadConfig if you are writing a tool that should find svgo.config.mjs. If you call the API from a build step, commit the config the build loads. A script with an inline plugin list that nobody else can see is a second optimizer.
What not to let the optimizer decide
Do not let an optimizer invent a color system. If the icon should follow the text color, that decision belongs in the source, as a paint you chose, before SVGO runs. If a plugin inlines a style into a presentation attribute, check that the color you wanted survived. The README’s override example touches inlineStyles for a reason: styles are easy to rewrite in a way that still “renders” and no longer matches the component.
Do not optimize the guide artboard. Grid lines, hidden labels, and editor notes are authoring. The README says hidden elements are the kind of thing SVGO can remove. That is useful on an export. It is destructive on the master if the master is the only copy of the guides. Export a copy, optimize the copy, keep the master.
Do not treat a smaller file as proof the icon is the same. Look at it. A path that moved by a rounding you did not notice is still a different path. Put the optimized icon in the component and look at two sizes you ship. SVGO’s own reason for existing is removal that does not affect rendering. Hold it to that sentence from the README.
Custom plugins are possible. The README shows an imported plugin and an inline plugin with a fn. Do not add one until a default plugin has failed in a way you can describe. A custom plugin is code you now maintain. An override on the default preset is a line in a config the next person can read.
License is MIT, which the README states, with the license file linked from the repository. Logo credit on that page goes to André Castillo. Those are statements about the tool, not about the icons you pass through it. Your icon set keeps whatever license it already had. Optimizing a file you do not have rights to does not create those rights.
Tomorrow, take one exported icon, run SVGO into a second file using the default preset, and open both at the size the button uses. If they match, commit a config that records that preset and point the output at the shipping folder. If they do not match, disable the plugin that caused it, using the override shape the README shows, and run the one file again. Do not run the folder until the one file looks right.
When someone pastes a new SVG from an editor, it goes through that same command before review. A file that skips the command brings editor metadata back into the set, which is the redundancy the README describes. The review compares the optimized output to the component, not the editor preview to a screenshot.
Keep the config next to the icons. A config in a personal dotfile will not run in CI. The build should fail or at least warn when the optimized output was not regenerated, so a hand-edited SVG does not skip the step. SVGO only helps if the command that worked once is the command that runs every time.
Look at the diff, not only the preview. A metadata strip changes a lot of lines and almost none of the picture. A path rewrite changes fewer lines and the picture. If you cannot explain the diff in one sentence, do not ship that output. The sentence is either “editor junk removed” or “this plugin moved a path, so it is disabled.” Anything else means you have not looked.
Pin the version in the project. The README’s install commands are the starting point, and a floating global binary will not match the config you committed. When the tool updates, run the one-file comparison again before you update the folder. A new version can change a default plugin. The config file is the record of what you allowed, and it should be reviewed like any other change to the icons.