CI/CD & Automation

Optimizing SVGO for CI/CD Pipelines

A hardened, production-tested SVGO configuration guide: preventing broken viewBoxes, avoiding gradient collisions with prefixIds, and automating pull-request linting.

TL;DR — The Gold-Standard SVGO Config

Never run SVGO with default settings in CI/CD. Explicitly configure removeViewBox: false to maintain responsive CSS scaling, enable prefixIds: true to avoid global gradient/mask clashes, set floatPrecision: 2 for high byte savings without path distortion, and convert inline styles to presentation attributes.

The Risks of Default SVGO in Automated Pipelines

SVGO (SVG Optimizer) is the industry standard tool for minifying vector assets. However, using out-of-the-box defaults inside a continuous integration pipeline frequently breaks user interfaces in subtle ways:

The Hardened svgo.config.mjs

Here is the battle-tested configuration used across production design systems to achieve 60–80% size reductions without visual breakage:

// svgo.config.mjs
export default {
  multipass: true, // Run optimization passes repeatedly until optimal
  plugins: [
    {
      name: 'preset-default',
      params: {
        overrides: {
          // CRITICAL: Preserve viewBox for responsive CSS scaling
          removeViewBox: false,
          
          // Disable over-aggressive path merging that breaks multi-color icons
          mergePaths: false,
          
          // Strip comments, metadata, and editor namespaces (Figma, Illustrator)
          removeComments: true,
          removeMetadata: true,
          removeEditorsNSData: true
        }
      }
    },
    // Prefix internal IDs (masks, gradients) with file hash to avoid collisions
    {
      name: 'prefixIds',
      params: {
        prefixIds: true,
        prefixClassNames: false
      }
    },
    // Convert inline style="" tags into CSS presentation attributes (fill, stroke)
    {
      name: 'convertStyleToAttrs'
    },
    // Set 2 decimal float precision: saves 40% bytes with zero visual warping
    {
      name: 'cleanupNumericValues',
      params: {
        floatPrecision: 2
      }
    },
    // Sort attributes deterministically for cleaner git diffs
    {
      name: 'sortAttrs'
    }
  ]
};

Automating SVGO with GitHub Actions

Add a lightweight GitHub Action workflow to automatically optimize all committed vector assets on pull requests:

# .github/workflows/optimize-svgs.yml
name: Optimize SVGs
on:
  pull_request:
    paths:
      - 'src/assets/icons/**.svg'

jobs:
  svgo:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install SVGO
        run: npm install -g svgo

      - name: Run SVGO Optimization
        run: svgo -f src/assets/icons --config svgo.config.mjs

      - name: Commit Optimized Vectors
        uses: stefanzweifel/git-auto-commit-action@v5
        with:
          commit_message: "chore(icons): auto-optimize SVGs via SVGO"

Local Git Pre-Commit Hook with lint-staged

To prevent unoptimized 50 KB Figma exports from ever reaching the remote repository, configure a pre-commit hook in package.json:

{
  "lint-staged": {
    "src/assets/icons/**/*.svg": [
      "svgo --config svgo.config.mjs",
      "git add"
    ]
  }
}

Frequently Asked Questions

Does SVGO strip currentColor attributes?

Not unless explicitly configured. SVGO preserves fill="currentColor" and stroke="currentColor" presentation attributes when using our recommended preset.

Why is floatPrecision 2 recommended over 0 or 1?

A precision of 0 rounds coordinates to whole integers, causing visible jagged steps on smooth Bézier arcs at 16px/24px icon sizes. Precision 2 retains subpixel curve smoothness while eliminating meaningless trailing decimals.

Need Clean, Pre-Optimized Icons?

Every single one of the 134,000+ vector icons on IconStash is already losslessly optimized, standardized, and production-ready.

Search All 134K+ Icons →