Getting a clean, responsive SVG icon set out of Figma without any raster fallbacks is one of those small victories that saves time and preserves quality across web and product builds. I’ve iterated on a few workflows and landed on a compact plugin chain that lets me prepare, export, and optimize SVG icons entirely from Figma — keeping everything vector, preserving viewBox, and removing width/height so icons scale responsively in CSS.

Why this matters

When an SVG contains embedded bitmaps or Figma-export defaults that hardcode width/height, you lose the benefits of vector graphics: crispness at any size, tiny file size, and easy styling with CSS. Design teams and developers often end up re-exporting or cleaning icons later in a separate pipeline. I prefer to ship icons from Figma already optimized for the web, so teams can drop them in without extra steps.

Overview of the plugin chain I use

The goal is simple: standardize names and frames, convert any non-vector elements into pure vectors, export SVGs, and run an optimization pass that removes width/height attributes while keeping a correct viewBox. The chain I rely on in Figma is:

Step Plugin Purpose
1 Rename It Normalize icon names for consistent export (optional but saves headaches)
2 Outline Stroke / Vectorize Convert strokes and boolean operations to pure vector paths
3 Export Icons (Batch SVG) Export each frame/artboard as an SVG file
4 SVGO Compressor (plugin) Run SVGO optimizations inside Figma and remove width/height while keeping viewBox

Note: exact plugin names in the community may vary slightly (Figma’s plugin ecosystem changes often). The important part is the function: name, vectorize, batch export, then run SVGO-style optimization. If a plugin with the same exact name isn’t available, look for equivalents that expose the same capabilities — e.g., any batch SVG export plugin + an in-Figma SVGO wrapper or a quick post-export SVGO CLI step.

Preparation inside Figma

Before hitting plugins, get the icons into a consistent state:

  • Put every icon in its own frame (I name frames like icon-name/size, e.g., search/24).
  • Set each frame’s background to transparent.
  • Make sure icons are vector-only: no image fills, no embedded bitmaps. If you have bitmap fills, replace them with SVG vectors or rebuild them.
  • Avoid complex masks and nested boolean ops where possible. Boolean operations are fine, but expand/flatten where necessary.
  • Standardize sizes and alignment: center icons in their frames and ensure consistent viewbox padding (I use a 2px safe zone for 24px icons).
  • Vectorization: strokes, masks, and booleans

    Figma can leave strokes as strokes, which might not render consistently across tools. I always convert strokes to paths and expand boolean shapes when needed.

  • Use a plugin like Outline Stroke or the built-in “Outline Stroke” (Shift+Cmd+O) to turn strokes into fills. This makes SVG output more predictable.
  • Flatten boolean groups into a single vector path where the boolean result matters. Plugins like “Flatten Selection to Vector” help avoid clipping/mask artifacts.
  • Remove unnecessary masks or convert them into clean vector shapes. Masks sometimes cause Figma to export clipPath elements that behave differently in browsers.
  • Consistent naming for batch export

    A reliable naming convention is a small productivity win. I use a pattern that indicates semantic name and pixel grid size: icon-name/24.svg. The Rename It plugin (or similar) helps if you have dozens or hundreds of icons to normalize.

    Batch SVG export from Figma

    Once your frames are named and vectorized, select them all and use your preferred batch export plugin (or Figma’s native export) to produce SVG files. Key export settings:

  • Format: SVG
  • Include: Outline text (if you used text — but ideally icons should be outlines)
  • Check that “Include id attributes” is enabled if you need them for CSS targeting — but be cautious: IDs must be unique.
  • Export at 1x — we want the canonical vector SVGs.
  • Run SVGO-style optimizations (inside Figma or immediately after)

    Here’s where many workflows diverge. You can download files and run SVGO locally, or use an in-Figma SVGO plugin to avoid leaving the app. The massive wins here are:

  • Remove width/height attributes while preserving viewBox
  • Minify path data (precision reduction)
  • Remove metadata, comments, and unnecessary ids or defs
  • Collapse groups where possible
  • If you use an in-Figma SVGO plugin (many community plugins wrap SVGO), configure it with these basic options:

  • preset: default
  • plugins:
  • removeDimensions: true (this strips width/height)
  • cleanupIDs: {remove: true} (optional)
  • convertPathData: true
  • Important: removeDimensions is the key to make SVGs responsive. It keeps the viewBox and eliminates fixed width/height attributes so your icons scale naturally with CSS width/height or font-size when used inline or as background images.

    Troubleshooting common edge cases

    Here are issues I’ve run into and how I handle them.

  • Stroke alignment changes after outline: Converting strokes to fills can slightly change visual weight. I tune stroke width before outlining or adjust final paths manually.
  • Masked layers producing clipPaths: If you need masks, try to flatten the mask into a compound path. Otherwise test the exported clipPath behavior in the target browser or app—some SVG consumers treat clipPaths differently.
  • Icons containing gradients or filters: Gradients are fine as SVG but can complicate the CSS editability. If you want icon color to be fully CSS-controlled, convert gradients to single fills or export separate color variants.
  • Fonts/text leaking into SVG: Always outline text in icons. Figma may embed font data otherwise, and that breaks portability.
  • Verification and developer handoff

    After export + optimization, I always verify a few things before handing the set to developers:

  • Open a few SVGs in a text editor and confirm there is a viewBox and no width/height attributes (or only if intentionally kept).
  • Drop the SVG inline in a simple HTML file and test resizing with CSS (for example, setting width: 2rem; height: auto; or font-size if used as an inline icon).
  • Check path precision — sometimes SVGO’s convertPathData introduces too aggressive rounding. If you notice jitter at small sizes, relax the precision setting.
  • Small automation table

    Here’s a compact checklist I follow each time I create a new icon set:

    TaskWhyPlugin/Action
    Frame per iconConsistent export unitFigma frames
    Normalize namesBatch export mappingRename It
    Outline strokes, flatten booleansPredictable SVG pathsOutline Stroke / Flatten
    Export SVGSource filesBatch SVG export
    Optimize (removeDimensions)Responsive, minimal SVGSVGO plugin or SVGO CLI

    Extra tips

  • If you want icons to be styleable with CSS fill or stroke, avoid hard-coded colors — use currentColor or leave paths without fill and set stroke on usage.
  • Consider exporting both inline SVGs and an SVG sprite if your project will benefit from a single-request sprite; the same optimization steps apply.
  • For design systems, store the optimized SVGs in a versioned asset folder and document the naming convention for consumers.
  • I find this approach keeps the design side in control of icon quality while giving devs ready-to-use assets. It reduces back-and-forth and ensures icons scale cleanly across breakpoints and UI contexts. If you want, I can share a sample SVGO config you can paste into the plugin or CLI to match the settings I described.