← All articles 11 min read

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.

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:

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.

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:

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.