SVGO: a plugin-driven SVG optimizer for Node.js and the command line
SVG Optimizer for Node.js and CLI. ⚙️
At a glance
- What is it?
- SVGO strips editor metadata, comments and redundant attributes from SVG files through a configurable plugin pipeline. It is a build-time tool, not a browser-side one, and its plugin order is the thing you actually tune.
- Who is it for?
- Adopt SVGO if you ship SVG icons or illustrations through a Node build and want the cleanup step scripted rather than done by hand in an editor. Do not adopt it if you need to optimize SVGs inside a browser page at runtime, or if your SVGs are hand-authored and you have no way to visually diff the output; the browser export exists, but the README frames SVGO as a Node.js library and command-line application.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 33 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The redundant bytes SVGO is built to remove
Files exported from vector editors carry information that has nothing to do with how the image renders. The README lists the categories directly: editor metadata, comments, hidden elements, and default or suboptimal values. A path that repeats a default fill, a group whose transform cancels out, an id that no other element references, a comment block naming the design tool and its version. None of that changes a pixel on screen, and all of it ships to every visitor.
The audience is anyone who puts SVG into a build. Icon sets, illustration libraries, sprite sheets, and static site assets are the obvious cases. The README is explicit that SVGO is a Node.js library and command-line application, so the mental model is a step in a pipeline, not a service you call at render time. If your SVGs are generated by a design tool and committed to a repository, SVGO is aimed at you. If they are hand-written and small, the gain is smaller than the config work.
How the plugin pipeline actually runs
SVGO is not a single transformer. It parses the SVG into an AST, runs a list of plugins over that tree, and serializes it back. The configuration file is where the plugin list lives, and the README shows it reading from svgo.config.mjs or from a path passed with --config.
By default you are not running plugins one by one. You run preset-default, which the README describes as the built-in plugins enabled by default, and you adjust it through an overrides object rather than by replacing the list. That distinction matters: an override can disable a default plugin by setting it to false, or pass new params to one, without you having to reconstruct the correct order yourself. The README points to the preset-default documentation for the list of default plugins in the order they run, which is the right place to look before reordering anything.
Plugins can also be added by name as a bare string, configured by passing an object with a name and params, imported from another JavaScript file, or defined inline as an object with a name, params and an fn function. The fn signature shown in the README is (ast, params, info). That is the extension point: if a transformation you want does not exist, you write it against the same AST the built-in plugins receive. The cost is that you now own the correctness of that transformation across SVG features you may not have considered.
Installing SVGO and optimizing a first file
Install it globally with npm, yarn or pnpm. The README gives all three; the npm form is the one most people will type.
npm install -g svgoAfter that, svgo is on your PATH. To process a single file and write the result elsewhere, the README uses the -o flag with an output path. Note that the flag takes one output per input, in the same order.
svgo one.svg two.svg -o one.min.svg two.min.svgFor a directory, combine -r (recursive) with -f (folder) and point -o at an output directory.
svgo -rf path/to/directory_with_svgs -o path/to/output_directoryIf your project needs a non-default plugin set, create svgo.config.mjs in the working directory. This example, adapted from the README, keeps the default preset but disables cleanupIds and relaxes inlineStyles so it processes styles that are matched more than once.
export default {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
cleanupIds: false,
inlineStyles: {
onlyMatchedOnce: false,
},
},
},
},
],
};Run svgo again on the same input and the new config is picked up. To use SVGO from code instead of the CLI, import optimize and pass the SVG source as a string. The README recommends including a path, which plugins may use for reporting.
import { optimize } from 'svgo';
const result = optimize(svgString, {
path: 'path-to.svg',
multipass: true,
});
const optimizedSvgString = result.data;If you are building a tool on top of SVGO, loadConfig resolves the config file for you, optionally with a path and a working directory.
import { loadConfig } from 'svgo';
const config = await loadConfig();Where the defaults will bite you
The preset is opinionated, and the plugins that remove the most bytes are also the ones most likely to break something. cleanupIds is the clearest example: it removes ids it believes are unused, but ids are also referenced from CSS, from JavaScript, from external files, and from url(#...) references in attributes the plugin may not track. The README's own override example disables cleanupIds, which tells you the maintainers consider it a plugin people turn off.
inlineStyles is the second. Its onlyMatchedOnce parameter, shown set to false in the README example, controls whether styles matched more than once are inlined. Leaving it at its default is the conservative choice; flipping it can change how a stylesheet cascade resolves, and the README does not describe the failure modes.
There is also a versioning hazard. The releases list shows v4.1.0, v3.3.5 and v2.8.4 all published on 2026-08-24, so three major lines are being maintained in parallel. A config written against one major line is not automatically correct on another, and the preset-default plugin list can change between them. Pin your SVGO version in a project that depends on specific plugin behaviour.
Finally, SVGO is the wrong tool for runtime optimization. It is packaged for Node, and the README positions it as a library and CLI. If you need to shrink an SVG in the browser after the user uploads it, you are looking at the browser export rather than the documented workflow, and the README does not walk through that case.
SVGO compared with SVGR's plugin path
SVGR solves a different problem: turning an SVG into a React component. It ships an SVGR plugin named svgr/plugin-svgo, which runs SVGO as part of that conversion. The difference in approach is the unit of work. SVGO operates on the SVG document and hands back an optimized SVG string or file. SVGR operates on the component boundary and hands back JavaScript or TypeScript, using SVGO only to clean the markup before it is transformed.
That means the two are not substitutes. If you want an .svg file that is smaller, SVGO is the tool. If you want a React component that renders an icon and accepts props, SVGR is the tool, and its SVGO plugin is how you keep the markup tidy along the way. Choosing SVGO as an alternative to SVGR would leave you writing the component wrapper yourself; choosing SVGR as an alternative to SVGO would leave you with a component you cannot ship to a non-React consumer. The plugin config keys are the shared surface, so an overrides block you tune for one generally carries over to the other.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-08-27, which is recent. Releases across three major lines landed on 2026-08-24, including v4.1.0. That pattern, backporting to v2 and v3 alongside v4, is a real maintenance commitment and also a signal that migration between majors is not free; if it were, the older lines would not need patches.
The package is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a summary of the licence identifier in the repository, not legal advice; read the LICENSE file if your organisation has specific obligations.
Upgrade cost concentrates in the config. Because preset-default decides which plugins run and in what order, a major upgrade can change output without any change to your svgo.config.mjs. The mitigation is a fixture test: keep a directory of representative SVGs, run the CLI over it, and diff the output between versions. The README does not document a rollback path or a compatibility table between majors, so that diff is something you construct. The repository does ship a test directory and a vitest.config.js, which tells you the project tests itself, but nothing in the README promises your specific SVGs are covered.
Editorial conclusion
Adopt SVGO if you ship SVG icons or illustrations through a Node build and want the cleanup step scripted rather than done by hand in an editor. Do not adopt it if you need to optimize SVGs inside a browser page at runtime, or if your SVGs are hand-authored and you have no way to visually diff the output; the browser export exists, but the README frames SVGO as a Node.js library and command-line application. Before rolling it into a pipeline, run it over a copy of your real icon set, open the results in a browser, and check the plugins you disabled or overrode, because preset-default changes between major versions and a config that names cleanupIds or inlineStyles is pinning behaviour that the preset would otherwise decide for you.
Frequently asked questions
What is SVGO and what is it used for?
SVGO stands for SVG Optimizer. It is a Node.js library and command-line application that removes redundant information from SVG files, such as editor metadata, comments, hidden elements and default or suboptimal values, without affecting rendering.
How do I install the SVGO CLI?
Install it globally with npm, yarn or pnpm. The README gives npm install -g svgo, yarn global add svgo and pnpm add -g svgo. Dropping the global flag installs it into a Node.js project instead.
Where does SVGO read its configuration from?
From svgo.config.mjs in the working directory, or from a path passed with the --config command-line option. Some parameters can also be set through command-line options.
Can I disable a plugin that preset-default turns on?
Yes. Set the plugin to false inside the preset-default params.overrides object, as the README does with cleanupIds. You can also pass new params to a default plugin the same way, as the README shows with inlineStyles.
Does SVGO work as a library as well as a CLI?
Yes. The README documents an optimize function that takes an SVG string plus options and returns result.data, and a loadConfig function for resolving the config file when you build a tool on top of SVGO.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/svg-svgo)