The big idea: there are only three ways to ship an SVG — and one usually wins

Every icon in your app gets to the browser one of three ways. Picking wrong costs you theming, performance, or both.

1. <img src="icon.svg"> — cacheable and simple, but a dead end: you can't restyle it with CSS. Your dark mode now needs a second file per icon. Use it only for icons that never change color (logos, illustrations).

2. Inline <svg> — the SVG markup lives in your HTML/JSX. Full CSS control, no extra requests, and it unlocks the one attribute this whole edition hinges on:

svg { color: inherit; }

Set your icon's fills/strokes to currentColor and the icon inherits text color — hover states, dark mode, disabled states, all free:

<button class="danger">
  <svg fill="currentColor"></svg> Delete
</button>

The icon turns red because the button text is red. No icon-specific CSS. Ever.

3. SVG sprite (<use href="#icon-x">) — one cached file, tiny DOM. The right call at serious scale (hundreds of icon instances per page), with the tradeoff that per-instance multi-color styling gets fiddly.

Default recipe for a React/Vue app: inline SVGs as components, currentColor everywhere, and don't sweat sprites until you've measured a problem. Component frameworks dedupe the markup at author time anyway — the "inline bloats your bundle" fear mostly predates componentization.

Clarification: components reduce authoring duplication, but every inline instance still emits SVG markup in the DOM. Measure before moving to a sprite.

60-second tip

Add flex-shrink: 0 to your icon SVGs. Inside flex rows — buttons, list items, nav — a long text label will otherwise squash the icon into an oval. One line, and you stop re-fixing that bug component by component.

Steal this: a production-grade <Icon> wrapper

This week's asset is a small React component that handles what everyone forgets: size presets locked to a 16/20/24 scale, currentColor inheritance, aria-hidden by default with an opt-in label prop for meaningful icons, and stroke-width consistency. TypeScript, zero dependencies, ~40 lines. Vue version included.

And to skip the download-unzip-copy dance in the first place: any icon on IconBuddy copies straight out as a JSX/TSX or Vue component, currentColor conversion included — search, copy, paste.

Before you go

Are you team inline, team sprite, or team img-tag-and-proud? Reply with your setup — genuinely curious how this splits across the list, and we'll share the tally.

How are you enjoying Iconic so far? Reply with one thing you want more of — or one thing we should change. We read every reply.

— Iconic, by IconBuddy

m_content=ps