How to Compress SVG Files: Tools, Techniques, and Config
SVG files are text. Specifically, they are XML — a tree of elements describing paths, shapes, gradients, filters, and metadata. Unlike raster formats (PNG, JPEG, WebP), compressing SVG has nothing to do with pixel data or color depth. It means stripping redundant XML nodes, simplifying path definitions, removing editor junk, and delivering the cleaned result with transfer-level compression.
A typical icon exported from Illustrator v29 weighs 45KB. After optimization, the same icon renders identically at 8KB. That is an 82% reduction with zero visual change — and the file is still a fully editable vector.
This guide covers every layer of SVG compression: automated tools, manual cleanup techniques, server-side delivery, and Illustrator export settings that prevent bloat in the first place.
Working with images?
Pixotter compresses raster images (PNG, JPEG, WebP) in-browser with no upload and no signup. Drop, compress, download.
Why SVG Compression Is Different
Raster compression reduces pixel data — fewer colors, approximate values, smaller grids. SVG compression reduces text. The file is XML source code, and like any source code, it accumulates cruft:
- Editor metadata. Illustrator, Figma, and Inkscape each embed their own XML namespaces, layer names, generator comments, and internal IDs. None of this affects rendering.
- Redundant attributes.
fill="#000000"on an element that inheritsfill="#000000"from its parent.style="display:inline"on an element that is inline by default. - Verbose path data. Path commands with 8 decimal places when 2 would produce identical on-screen output. Absolute coordinates where relative deltas would be shorter. Curves that approximate straight lines.
- Invisible elements. Hidden layers, zero-opacity groups, elements fully clipped outside the viewBox.
- Embedded raster data. Some export flows embed PNG or JPEG thumbnails as base64 data URIs inside the SVG. A 200-byte icon suddenly weighs 40KB.
Removing this waste does not change what the browser draws. The rendering engine ignores metadata, recomputes inherited styles, and rounds sub-pixel coordinates anyway. You are deleting what the browser already discards.
Try it yourself
Reduce file size without visible quality loss — free, instant, no signup. Your images never leave your browser.
SVG Compression Techniques Compared
| Technique | Tool / Method | Typical Savings | Quality Risk | Automation | Best For |
|---|---|---|---|---|---|
| Automated optimization | SVGO v3.3.2 | 40–80% | None (safe defaults) | CLI, Node.js API | All SVGs — the baseline step |
| Manual cleanup | Text editor | 10–30% (on top of SVGO) | None if careful | Manual | Complex SVGs where SVGO misses domain-specific waste |
| Transfer compression | gzip / brotli | 60–75% additional | None | Server config | All SVGs served over HTTP |
| Export settings | Illustrator v29 | Prevents 50–90% of bloat | None | Per-export | Designers producing SVGs |
| Online tools | SVGOMG, Pixotter | 40–70% | Depends on settings | Browser-based | Quick one-off jobs |
These techniques stack. SVGO strips XML waste, manual cleanup catches what SVGO cannot, and gzip/brotli compresses the cleaned text for transfer. An icon that starts at 45KB → 8KB after SVGO → 2.5KB over brotli.
SVGO: The Standard SVG Optimizer
SVGO (SVG Optimizer, MIT license) is the de facto tool for SVG compression. Most online SVG optimizers — including SVGOMG — are wrappers around SVGO. If you only learn one tool from this guide, this is the one.
Install and Basic Usage
SVGO v3.3.2 requires Node.js v22 or later.
# Install SVGO v3.3.2 globally
npm install -g svgo@3.3.2
# Compress a single SVG
svgo input.svg -o output.svg
# Compress in-place (overwrites the original)
svgo input.svg
# Compress all SVGs in a directory
svgo -f ./icons/ -o ./icons-optimized/
# Compress recursively
svgo -f ./assets/ -o ./assets-optimized/ -r
With default settings, SVGO removes metadata, strips comments, merges paths, collapses useless groups, converts colors to shortest form, and optimizes path data. Default behavior covers 90% of cases.
Custom Configuration
For more control, create an svgo.config.mjs file in your project root:
// svgo.config.mjs — SVGO v3.3.2 configuration
export default {
multipass: true, // Run multiple passes until no more savings
plugins: [
{
name: 'preset-default',
params: {
overrides: {
// Keep viewBox (needed for responsive scaling)
removeViewBox: false,
// Reduce path precision from default 3 to 2
// Saves bytes on complex paths, safe for most icons
cleanupNumericValues: {
floatPrecision: 2,
},
// Keep IDs used by CSS or JavaScript
// Set to false if your SVGs have meaningful IDs
cleanupIds: {
remove: true,
minify: true,
},
},
},
},
// Remove Illustrator/Inkscape-specific elements
'removeEditorsNSData',
// Sort attributes for better gzip compression
// (repeated patterns compress better when ordered consistently)
'sortAttrs',
// Convert inline styles to attributes where shorter
'convertStyleToAttrs',
],
};
Run SVGO with the config:
svgo --config svgo.config.mjs input.svg -o output.svg
Plugins That Matter
SVGO ships with 30+ plugins. These are the ones that produce the largest savings:
| Plugin | What It Does | Default On? |
|---|---|---|
removeDoctype |
Strips <!DOCTYPE> declaration |
Yes |
removeComments |
Strips XML comments | Yes |
removeMetadata |
Strips <metadata> elements |
Yes |
removeEditorsNSData |
Strips Illustrator/Inkscape namespace data | Yes |
cleanupNumericValues |
Rounds numbers to floatPrecision decimals |
Yes (3 decimals) |
convertPathData |
Converts absolute to relative coords, removes redundant commands | Yes |
mergePaths |
Merges adjacent <path> elements with identical styles |
Yes |
collapseGroups |
Removes <g> wrappers that have no attributes |
Yes |
removeViewBox |
Removes the viewBox attribute |
Yes (override this to false) |
sortAttrs |
Orders attributes alphabetically for gzip efficiency | No |
One override you should always apply: disable removeViewBox. The viewBox attribute is essential for responsive SVGs that scale to their container. Without it, your SVG has a fixed pixel size.
Build Pipeline Integration
For projects using a bundler, add SVGO to your build step:
# package.json script — compress all SVGs before build
# Requires: npm install -D svgo@3.3.2
{
"scripts": {
"optimize:svg": "svgo -f ./src/assets/icons -o ./src/assets/icons -r",
"build": "npm run optimize:svg && vite build"
}
}
For Vite projects specifically, vite-plugin-svgo (MIT license) runs SVGO on SVG imports at build time.
Manual SVG Optimization Techniques
SVGO handles the mechanical work. Manual optimization handles the domain-specific work — things that require understanding what the SVG represents to know what can be simplified.
Remove Embedded Raster Data
Design tools sometimes embed raster previews or textures as base64 data URIs. Look for <image href="data:image/png;base64,..." elements. A single embedded PNG can add 30–100KB to an icon that should be 2KB. Remove these elements entirely, or replace the raster texture with an SVG pattern.
Simplify Path Coordinates
SVGO reduces decimal precision, but you can go further for simple shapes. An icon path with coordinates like M 12.003906 4.003906 L 12.003906 20.003906 is storing precision the screen cannot display. At icon sizes (16–48px), two decimal places are more than enough. At large sizes, three decimals cover every display density up to 8K.
Replace Inline Styles with CSS
If an SVG has many elements sharing the same style, a single CSS rule is shorter than repeating inline style attributes:
<!-- Before: 340 bytes of repeated inline styles -->
<rect style="fill:#3b82f6;stroke:#1e40af;stroke-width:2" ... />
<rect style="fill:#3b82f6;stroke:#1e40af;stroke-width:2" ... />
<rect style="fill:#3b82f6;stroke:#1e40af;stroke-width:2" ... />
<!-- After: 180 bytes with a shared class -->
<style>.box{fill:#3b82f6;stroke:#1e40af;stroke-width:2}</style>
<rect class="box" ... />
<rect class="box" ... />
<rect class="box" ... />
This saves bytes and makes the SVG easier to theme with external CSS.
Merge Overlapping Paths
Two <path> elements with identical fill and stroke can often be combined into a single <path> with a compound path definition (multiple M commands in one d attribute). SVGO's mergePaths plugin does this automatically for adjacent same-style paths, but it cannot merge paths separated by other elements. Manual reordering + merge can squeeze out another 5–15%.
Remove Hidden Elements
Check for:
- Elements with
display="none"orvisibility="hidden" - Elements with
opacity="0" - Groups that contain nothing after cleanup
- Elements positioned entirely outside the
viewBox - Clip paths that clip everything away
Design tools often leave hidden layers in the export. They contribute zero pixels and full bytes.
Server-Side Compression: gzip and Brotli
SVG is text. Text compresses exceptionally well with general-purpose algorithms. Serving SVG without transfer compression is leaving 60–75% of the bandwidth savings on the table.
Both gzip and Brotli operate at the HTTP layer — the SVG file stays the same on disk, but the server compresses it during transfer, and the browser decompresses it transparently. Every modern browser supports both.
Nginx Configuration
# /etc/nginx/nginx.conf — enable compression for SVG
gzip on;
gzip_types image/svg+xml;
gzip_min_length 256;
gzip_comp_level 6;
# Brotli (requires ngx_brotli module)
brotli on;
brotli_types image/svg+xml;
brotli_min_length 256;
brotli_comp_level 6;
Apache Configuration
# .htaccess or httpd.conf
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
# Brotli (requires mod_brotli, Apache 2.4.26+)
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule>
Pre-Compression for Static Sites
If your SVGs are static assets, pre-compress them at build time for maximum compression without runtime CPU cost:
# Pre-compress with gzip (maximum compression)
gzip -k -9 icon.svg
# Creates icon.svg.gz alongside icon.svg
# Pre-compress with brotli (maximum compression)
brotli -k -q 11 icon.svg
# Creates icon.svg.br alongside icon.svg
Configure Nginx to serve the pre-compressed version when the browser supports it:
gzip_static on;
brotli_static on;
Transfer Compression Savings
| File | Raw | After SVGO | Over gzip | Over Brotli |
|---|---|---|---|---|
| Icon (simple, 24px) | 2.1 KB | 0.8 KB | 0.4 KB | 0.35 KB |
| Logo (moderate complexity) | 18 KB | 6 KB | 2.1 KB | 1.8 KB |
| Illustration (complex) | 120 KB | 45 KB | 14 KB | 11 KB |
| Icon set (50 icons, combined) | 95 KB | 32 KB | 9 KB | 7 KB |
Brotli consistently beats gzip by 15–20% on SVG content. If your server supports both (and most CDNs do), prefer brotli with gzip as fallback.
Illustrator v29 SVG Export Settings
The best compression happens before you even run SVGO — at export time. Illustrator v29's File > Export > Export As > SVG dialog has settings that control how much junk ends up in the file.
| Setting | Recommended Value | Why |
|---|---|---|
| Styling | Presentation Attributes | Shortest output. Inline styles and Internal CSS are verbose. |
| Font | Convert to Outlines | Eliminates font embedding. If the SVG uses text, outline it. |
| Images | Link (not Embed) | Prevents base64 raster data from bloating the file. Remove linked images if not needed. |
| Object IDs | Layer Names or Minimal | "Layer Names" keeps meaningful IDs for CSS/JS targeting. "Minimal" is smallest. |
| Decimal | 2 | Matches SVGO's recommended floatPrecision. Lower = smaller, but 1 can distort curves. |
| Minify | Yes | Strips whitespace and newlines. |
| Responsive | Yes | Adds viewBox and removes fixed width/height. Essential for responsive SVGs. |
With these settings, an Illustrator export is already 40–60% smaller than the default export. Running SVGO on top of that still removes Illustrator-specific namespace data and further optimizes paths, but you start from a much cleaner baseline.
Figma note: Figma's SVG export is cleaner than Illustrator's by default — no namespace junk, no embedded rasters. SVGO still helps (path optimization, attribute sorting), but the starting point is smaller.
Before and After: Real Compression Results
These numbers come from compressing a set of UI icons originally exported from Illustrator v29 with default settings:
| Asset | Original | After Illustrator Settings | After SVGO v3.3.2 | Over Brotli | Total Reduction |
|---|---|---|---|---|---|
| Shopping cart icon | 12 KB | 6.2 KB | 2.1 KB | 0.9 KB | 92% |
| Navigation hamburger | 4.8 KB | 2.4 KB | 0.6 KB | 0.3 KB | 94% |
| User avatar placeholder | 28 KB | 14 KB | 5.2 KB | 1.8 KB | 94% |
| Company logo (moderate) | 45 KB | 22 KB | 8 KB | 2.8 KB | 94% |
| Detailed illustration | 180 KB | 95 KB | 52 KB | 16 KB | 91% |
The pattern: simple icons see 90–95% total reduction. Complex illustrations see 85–92%. The biggest single gain comes from SVGO, but each layer compounds.
For an icon set of 50 files totaling 450KB, the optimized + brotli-compressed set totals under 30KB. That is the difference between a noticeable load delay and instant rendering.
When NOT to Compress SVG
SVG compression is not always safe. Two scenarios require caution:
Complex Illustrations with Precise Curves
Path simplification works by removing control points and reducing decimal precision. For simple icons, this is invisible. For detailed illustrations — botanical drawings, architectural plans, typographic art — reducing floatPrecision below 3 can visibly distort curves. Test at the actual display size before committing.
If you see curve distortion after SVGO, increase floatPrecision to 3 or 4 in the config and disable convertPathData for that specific file:
// svgo.config.mjs — conservative settings for detailed SVGs
export default {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
cleanupNumericValues: { floatPrecision: 4 },
convertPathData: false, // Preserve original path commands
removeViewBox: false,
},
},
},
],
};
SVGs with JavaScript or Animation Dependencies
SVGO's cleanupIds plugin minifies element IDs. If your SVG has JavaScript that references elements by ID (document.getElementById('my-icon-path')) or CSS animations targeting specific IDs (#my-icon-path { animation: spin 2s; }), minified IDs break those references. Either disable cleanupIds or use class-based selectors instead.
Similarly, collapseGroups removes structurally insignificant <g> elements. If your JavaScript traverses the SVG DOM expecting specific group nesting, disable this plugin.
How Pixotter Handles SVG
Pixotter is built for raster image optimization — compressing PNGs, JPEGs, and WebP files in-browser via WebAssembly. SVG is a vector format and requires a fundamentally different optimization pipeline (XML manipulation rather than pixel-level compression).
For raster workflows that involve SVG, Pixotter fits into the pipeline at the conversion step. If you need to convert SVG to PNG for a context that requires raster output, convert SVG to JPG for email compatibility, or convert SVG to PDF for print-ready files, Pixotter handles the raster side — compressing the converted output to the smallest file size with zero quality loss.
For SVG-specific optimization, use SVGO as described above. For the raster images in your project, Pixotter's compress tool handles everything client-side with no upload and no signup.
Frequently Asked Questions
Does compressing SVG reduce visual quality?
Not with default SVGO settings. The default plugins remove metadata, comments, editor data, and redundant attributes — none of which affect rendering. Path optimization with floatPrecision: 3 (the default) produces sub-pixel differences invisible on any display. Reducing precision to 1 can distort complex curves, so test at the target display size if you go below 2.
What is the best tool to compress SVG?
SVGO v3.3.2 is the industry standard. It is open source (MIT license), actively maintained, used by nearly every SVG optimization tool, and runs on any system with Node.js v22. For a browser-based interface, SVGOMG is a wrapper around SVGO with a visual diff preview. For quick raster image compression, Pixotter handles PNG, JPEG, and WebP.
Can I compress SVG without installing anything?
Yes. SVGOMG runs entirely in the browser — paste your SVG or upload the file, toggle plugins, and download the result. No install, no signup. For raster image compression with the same zero-install approach, Pixotter works the same way.
Should I gzip SVG files?
Absolutely. SVG is XML text and compresses 60–75% under gzip, 65–80% under brotli. Always enable transfer compression for SVG on your web server. This stacks with SVGO optimization — a file cleaned by SVGO and served with brotli can be 95% smaller than the original over the wire.
Is SVG or PNG smaller for icons?
SVG is almost always smaller for simple icons. A 24px icon is typically 0.5–2KB as SVG versus 3–8KB as PNG (including 2x retina version). SVG also scales to any size from a single file, eliminating the need for multiple resolution variants. See the SVG vs PNG comparison for a full breakdown, or the best image format for web guide for choosing across all formats.
How much can I compress an SVG file?
It depends on the source. Design tool exports with default settings typically compress 70–90% after SVGO + server-side brotli. Hand-coded SVGs or already-optimized files may only compress 10–20%. Icons see the highest ratios; complex illustrations see the lowest. The transfer compression table above shows real numbers by asset type.
Does SVG compression affect accessibility?
SVGO preserves <title> and <desc> elements by default (the removeTitle and removeDesc plugins are off). These elements provide accessible names for screen readers. If you enable those plugins manually, you remove the accessible labels. Keep them disabled unless you provide accessibility via aria-label on the SVG element instead.
Try it yourself
Resize to exact dimensions for any platform — free, instant, no signup. Your images never leave your browser.