svgo

A Node.js library and command-line tool that optimizes SVG files by removing redundant markup through a configurable plugin pipeline.

Tool
npm
v4.1.0
22,765 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
87 /100 Excellent
Development Activity 92
Maintenance 80
Community 76
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
79 /100 Good
Architecture 85
Code Quality 82
Innovation 65
Learning Curve 85

SVGO (SVG Optimizer) strips the bloat that vector editors like Illustrator, Sketch, and Figma leave behind in exported SVG files — editor metadata, comments, hidden elements, redundant IDs, default attribute values, and other markup that has no effect on rendering. It ships both as a global CLI (svgo file.svg -o file.min.svg) and as an importable optimize() function for build pipelines, bundler plugins, and asset-processing scripts.

Under the hood it parses SVG into an internal AST via a SAX-based parser, runs a configurable chain of 30+ built-in plugins over that tree (each targeting one specific class of redundancy — collapsing groups, merging paths, converting shapes to path data, cleaning numeric precision), then re-serializes the optimized tree back to a string. The default plugin set (preset-default) can be selectively overridden, extended with custom plugins, or replaced outright via svgo.config.mjs.

SVGO is a foundational piece of the front-end asset pipeline for a large share of the JavaScript ecosystem: it’s the optimizer underneath most SVG-handling Webpack/Vite/Rollup loaders, icon-sprite generators, and static-site build tools. Its multipass mode reruns the plugin chain until output size stops shrinking, squeezing out savings later passes alone would miss.

What You Get

  • A global CLI (svgo) for optimizing single files or entire directories recursively
  • An importable optimize() function for embedding SVG optimization directly in Node.js code or bundler plugins
  • 30+ built-in plugins covering redundant metadata removal, path/shape merging, numeric cleanup, color conversion, and ID minification
  • A preset-default plugin bundle that can be selectively overridden per-plugin via svgo.config.mjs
  • Support for fully custom plugins defined inline or imported from other files
  • A loadConfig() helper so downstream tools built on SVGO can resolve the same config-file convention

Common Use Cases

  • Optimizing exported SVG icons and illustrations before shipping them to production
  • Running as part of a Webpack, Vite, or Rollup asset pipeline to auto-minify imported SVGs
  • Batch-processing an entire directory of design-tool exports via the recursive CLI flags
  • Stripping editor cruft (Illustrator/Sketch/Figma metadata) from SVGs before committing them to a repo
  • Generating compact base64/URL-encoded data URIs from SVG source for inline embedding

Under The Hood

Architecture

SVGO runs a strict three-stage pipeline: parser.js uses a SAX-based streaming parser (the sax dependency) to turn raw SVG text into an internal AST defined in xast.js, svgo.js’s optimize() function then walks that tree through invokePlugins() running each configured plugin from plugins/ in sequence, and stringifier.js serializes the transformed tree back to a string. Each plugin (in plugins/*.js, e.g. collapseGroups.js, convertPathData.js, cleanupIds.js) is a self-contained visitor targeting one narrow transformation, registered through createPreset() in plugins/preset-default.js so the default plugin set is just a curated list rather than special-cased logic. The svgo-node.js entry point wraps the platform-agnostic core (svgo.js) with Node-specific concerns — config-file resolution via loadConfig() and OS-appropriate line endings — while bin/svgo.js layers a Commander-based CLI (lib/svgo/coa.js) on top of that same core, so CLI, Node API, and browser bundle all share one optimization engine with no logic duplicated between entry points.

Tech Stack

The core has a deliberately small runtime dependency footprint: sax for XML parsing, css-tree/css-select/css-what for parsing and matching CSS selectors used by style-related plugins (inlineStyles.js, minifyStyles.js), csso for CSS minification, commander for CLI argument parsing, and picocolors for terminal output. The project is authored as native ESM (type: module) with a separate dist/ CJS/browser build produced by Rollup, and ships hand-written TypeScript declaration files built via tsc against tsconfig.build.json rather than being authored in TypeScript directly — most of lib/ and plugins/ remain plain JavaScript with JSDoc type annotations checked under strict mode. Testing runs on Vitest, with a separate test:regression pipeline that renders before/after SVGs with Playwright and diffs them pixel-by-pixel via pixelmatch to catch visual regressions the unit tests wouldn’t.

Code Quality

The repo has substantial test coverage — 18+ *.test.js files sit alongside their corresponding implementation files (parser.test.js, path.test.js, style.test.js, xast.test.js), plus a large fixture-driven plugin test suite and the separate pixel-diff regression suite for visual correctness, which is an unusually rigorous check for a text-transformation tool. ESLint (flat config, eslint.config.mjs) with eslint:recommended plus JSDoc/type-checking via tsc --strict on JS files (checkJs: true) stands in for a full TypeScript rewrite while still catching type errors; Prettier formats consistently, and CI (ci.yml, codeql.yml, regression.yml) runs lint, typecheck, unit tests, bundle tests, and the regression suite on every change. Error handling favors explicit thrown Errors with descriptive messages (e.g. unknown plugin names, malformed config) over silent fallbacks.

API Design The public API surface is intentionally minimal: a single optimize(svgString, config) function returning { data }, plus loadConfig() for config-file resolution — there’s no class hierarchy or builder pattern to learn. Configuration is a plain object matching the same shape whether it’s passed inline or loaded from svgo.config.mjs, and the plugin config format ('name' string, or { name, params } for built-ins, or { name, params, fn } for fully custom logic) scales smoothly from zero-config default use up to hand-written custom transforms without a second API to learn. This low-ceremony design is a large part of why SVGO is embedded inside so many other tools’ build pipelines rather than only used standalone.

Used by 23 apps in this directory

Python
82%
AGPL 3.0

SearXNG

Search

38,786

Privacy-first metasearch engine that aggregates results from 250+ search services — no tracking, no profiling, full control when self-hosted.

View details
80
Repo Health
82
Technical
73
Dependency
Built with
Python 82%
Updated 6 days ago
TypeScript
50%
Other

SigNoz

Analytics · Monitoring

32,429

Self-host your entire observability stack — logs, metrics, traces, and LLM monitoring — in one OpenTelemetry-native platform, without the Datadog bill.

View details
92
Repo Health
83
Technical
64
Dependency
Built with
TypeScript 50%
Go 38%
Updated 6 days ago
Go
75%
AGPL 3.0

Teleport

Authentication · Security

21,016

Zero-trust infrastructure access platform that replaces credentials and VPNs with short-lived certificates, SSO, and identity-aware proxies for SSH, Kubernetes, databases, RDP, and AI agents.

View details
94
Repo Health
81
Technical
68
Dependency
Built with
Go 75%
TypeScript 16%
Updated 1 weeks ago
TypeScript
99%
AGPL 3.0

Webstudio

Design Tools · No Code Platforms

9,103

Open source visual development platform with complete CSS control, headless CMS integration, and full infrastructure ownership

View details
91
Repo Health
79
Technical
60
Dependency
Built with
TypeScript 99%
Updated 6 days ago
Python
57%
Apache 2.0

Zulip

Team Chat

26,102

Topic-based team chat that brings the structure of email threads to real-time messaging, so distributed teams never lose context across hundreds of concurrent conversations.

View details
96
Repo Health
86
Technical
60
Dependency
Built with
Python 57%
TypeScript 19%
JavaScript 11%
Updated 6 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers