Scalable Vector Graphics (SVG)
SVGs scale without pixelation. They also bloat your bundle if you inline them carelessly.
The strategy depends on how many SVGs you have and whether they need runtime manipulation.
SVG Strategies
| Strategy | How | Bundle Impact | Runtime Control | Best For |
|---|---|---|---|---|
| Inline SVG | Paste SVG markup in JSX | Adds to component size | Full (props, CSS, animation) | Icons needing color/state changes |
| SVGR component | Build-time transform to React component | Tree-shakeable | Full | Icon libraries, design systems |
| SVG sprite | Single file, reference by use | One HTTP request | Limited (CSS only) | Large icon sets, static icons |
| img tag | <img src="icon.svg" /> | Separate HTTP request | None | Decorative, non-interactive |
| CSS background | background-image: url(...) | Cached by browser | None | Patterns, decorative backgrounds |
Decision Rule
| Question | If Yes | If No |
|---|---|---|
| Need to change color/state? | SVGR or inline | img tag or sprite |
| More than 20 icons? | Sprite or SVGR with tree-shaking | Inline is fine |
| Is it decorative only? | img tag or CSS background | Needs inline or SVGR |
| Part of a design system? | SVGR | Case by case |
Key Patterns
| Pattern | Why |
|---|---|
Remove hardcoded fill/stroke | Let CSS or props control color |
Set viewBox, remove width/height | Scale responsively |
Use currentColor for fills | Inherits text color automatically |
| Optimize with SVGO | Strip editor metadata, reduce file size |
Links
Context
- Components — SVGs are components when interactive
- Tailwind — Tailwind classes control SVG styling
- Performance — SVG strategy directly affects bundle size
- Design — Icon systems and visual consistency
Questions
When does an SVG sprite outperform individual SVGR components?
- What is the bundle cost of inlining vs. importing 50 SVG icons?
- How do you maintain SVG accessibility (role, title, desc) across a design system?
- When should you use a font icon set instead of SVGs?