SVG Optimizer

Minify SVG files with SVGO — strip editor metadata, round coordinates, and shrink output while keeping rendering intact.

Loading…

All processing runs in your browser — no files or inputs are uploaded to a server.

How to use

Paste an SVG (the whole `<svg>...</svg>` block, not a file path) and SVGO runs its default plugin chain in your browser: strip editor metadata (the `<sodipodi:...>` / `<inkscape:...>` / `<adobe-...>` namespaces that Figma, Illustrator, and Sketch export), round coordinates to a sensible precision, collapse useless groups, merge paths, and minify the output while keeping the rendered result pixel-identical. A side-by-side preview shows the original and optimized SVG, plus the byte-count delta — typical Figma exports shrink 60–80%.

Reach for this whenever you export icons or logos from a design tool. The exported file is usually 5–10× larger than necessary because design tools err on the side of preserving editability. Optimized SVG is what you commit to a repo, ship as a sprite, or inline into HTML. Optimization runs entirely in your browser through SVGO's WASM build — design assets never leave your machine, which matters when the file contains a confidential logo or unreleased iconography.

Examples

Figma export → optimized

Input
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check" data-figma-node="123:456">
  <!-- Generator: Figma 117.5.4 -->
  <metadata>
    <rdf:RDF xmlns:rdf="...">...</rdf:RDF>
  </metadata>
  <path d="M20.000000 6.000000 L9.000000 17.000000 L4.000000 12.000000"/>
</svg>
Output
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"><path d="m20 6-11 11-5-5"/></svg>

Bytes: 489 → 198 (-59%)

A typical icon export. The optimizer strips the metadata block, removes Figma-specific attributes (`data-figma-node`, the editor comment), drops trailing zeros on coordinates (`20.000000` → `20`), merges absolute moves into relative moves (`L9 17` becomes `-11 11`), and reformats to single-line. The visual result is byte-identical when rendered — the optimizer guarantees output produces the same pixels.

Preserve accessibility metadata

Input
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" role="img">
  <title>Settings</title>
  <desc>A gear icon representing settings</desc>
  <path d="M..."/>
</svg>
Output
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img"><title>Settings</title><desc>A gear icon representing settings</desc><path d="M..."/></svg>

`<title>` and `<desc>` are read by screen readers for the SVG's accessible name and long description (the SVG equivalent of `alt` text). The optimizer preserves them by default. If you see `<title>` getting stripped, check that the SVGO plugin `removeTitle` and `removeDesc` are disabled — most modern SVGO configs ship them disabled, but Figma's built-in optimizer is more aggressive and may need a config override.

Precision loss vs file size trade-off

Input
<svg viewBox="0 0 100 100">
  <path d="M50.123456 25.987654 C 50.123456 12.987654 39.123456 2.987654 25.987654 2.987654"/>
</svg>

precision: 2
Output
<svg viewBox="0 0 100 100"><path d="M50.12 25.99 50.12 12.99 39.12 2.99 25.99 2.99"/></svg>

(precision: 2 → ~50% fewer bytes per path point)

The default 3-decimal precision is a safe sweet spot. Lowering to 2 cuts more bytes for tiny icons (16×16, 24×24) where sub-pixel precision is wasted on a screen. Going below 1 starts to show artifacts on logo-quality SVGs at higher zoom; do not reduce precision blindly. Inspect the result at 2× or 4× zoom before committing.

FAQ

What does SVGO actually remove?

The default plugin set removes: XML comments, editor-specific namespaces (`sodipodi:`, `inkscape:`, `adobe-`), empty `<defs>` / `<g>`, unused IDs, duplicate `<filter>` / `<gradient>` definitions, redundant attributes (`xmlns:xlink` that goes nowhere), and `width` / `height` when `viewBox` is set. It also rewrites: round numbers to N decimals (default 3), merge `M...M` into chained `M` commands, convert absolute to relative path commands where shorter, and minify path data. The full list is in SVGO's `default-preset` (called `preset-default`) — about 30 plugins, each individually configurable.

Why does my optimized SVG look different in a browser vs Figma?

A few causes. **Figma renders extras** — guides, hidden layers, background canvas — that the exported SVG never had, so the "Figma view" and the "exported view" can differ on the original too. **Inheritance from CSS** — browsers cascade colors and fonts onto inline SVG via `currentColor`, `fill: var(...)`, and external font-family; Figma uses the values baked into the SVG. After optimization, if you stripped a `fill` attribute that was redundant inside Figma but needed in the browser, the icon may now show as black. Re-add the fill or use `currentColor` for hue-following icons.

Inline SVG, `<img src="...">`, or sprite — which should I use?

**Inline** (paste the SVG directly into HTML/JSX) when you need to style via CSS or animate — colors via `currentColor`, hover transforms, theme switches. **`<img src="icon.svg">`** when the icon is a static image with no dynamic styling — simpler, the browser caches the file across pages, and modern image-loading optimizations (lazy, decoding) apply. **Sprite** (`<symbol id="x">` + `<use href="#x">` references) for large icon libraries (Lucide, Heroicons) where loading 30 separate files would be slower than one combined file — one network request, deduplicated definitions. Vite, Webpack, and Next.js all have plugins to assemble sprites at build time.

How much does SVGO typically shrink a file?

Depends heavily on the source. **Figma / Sketch / Illustrator exports**: 60–80% reduction is typical — these tools emit verbose attributes and full editor metadata. **Hand-written SVGs**: 10–30% — already concise. **Old XML-y SVGs from clip art collections**: 70–90% — those often have decades of accumulated cruft. A 5 KB icon down to 1 KB is realistic; a 500 KB illustration down to 100 KB is also realistic. Gzip on the server then halves the wire bytes further, so optimization compounds nicely with HTTP compression.

Can SVGO break anything?

Yes, in three patterns. **ID-based references** between elements (`<use href="#foo">` or CSS targeting `#foo`) can break if SVGO renames or removes the ID — the `cleanupIds` plugin is the usual culprit; disable it for SVGs that participate in external references. **Animations** (`<animate>`, SMIL) that target a specific element by selector can fail when SVGO merges or restructures elements. **External CSS or JS hooks** into the SVG (a script that finds `<path data-name="logo">`) break if `data-*` attributes are removed; disable `removeUnknownsAndDefaults` for those cases. The optimizer is conservative by default but always preview the result before committing.

SVG vs PNG vs WebP for icons?

**SVG** for any icon that is simple shapes — sharp at any size, theme-able via CSS, often smaller than a PNG. **PNG** for icons with complex texture (skeuomorphic, photographic crops) where vector representation balloons the file. **WebP** is rare for icons because PNG is small enough at icon sizes and WebP's alpha channel quirks (older Safari) are not worth managing. Modern icon-heavy design systems are SVG-only (Lucide, Heroicons, Material Symbols, Phosphor); the file-size argument decisively favors SVG once you commit to a vector workflow.

Related concepts

SVG (Scalable Vector Graphics, W3C standard since 1999, current version 2.0 candidate recommendation) is an XML-based vector image format — shapes described by mathematical primitives (paths, circles, rectangles) rather than pixel grids. The advantage over raster is resolution independence: a 16-pixel and a 256-pixel render of the same SVG share the source file and stay sharp at every size. The cost is file complexity — an SVG describing a photograph would be enormous (every pixel as a tiny `<rect>`), so SVG dominates simple-graphic uses (logos, icons, charts) and stays out of photographic ones.

**SVGO (SVG Optimizer)** is the de facto JavaScript toolchain for shrinking SVG, originally written by Kir Belevich in 2012 and now maintained as `svgo` on npm. It works as a plugin pipeline — each plugin transforms the SVG AST (parsed via `xml-parser`-style traversal) and re-emits. Notable plugins: `removeComments`, `removeMetadata`, `cleanupIds`, `mergePaths`, `convertColors` (turns `#FFFFFF` into `#FFF` or `white`), `removeUselessStrokeAndFill`. The default preset enables about 30 of them; presets can be customized per project. SVGO also runs as an integrated step in build tools — `vite-plugin-svgr`, `@svgr/webpack`, `next/dynamic` for icon components — so optimization happens automatically on every commit.

Three adjacent concepts shape the SVG workflow. **`viewBox` vs `width`/`height`**: `viewBox` defines the coordinate system inside the SVG, `width`/`height` define the display size; an SVG with only `viewBox` scales to fit its container, an SVG with both is fixed. Most icon libraries set `viewBox` and omit `width`/`height` so the CSS owner can size the icon. **`currentColor`**: setting `fill="currentColor"` makes the SVG inherit the surrounding text color, which is how theme-able icons work. **SMIL animations** are SVG-native (`<animate>`, `<animateTransform>`) but Chrome's deprecation push in 2015 pushed everyone toward CSS animations and Lottie; SMIL works again in current browsers but is rarely written today. For complex animated illustrations, Lottie (JSON-based, Bodymovin export from After Effects) is the dominant choice; SVG handles static and CSS-animated cases.

Related tools