Complete Export Format Decision Matrix
| Export Format | JS Bundle Cost | Themeable via CSS? | Browser Cacheable? | Primary Production Fit |
|---|---|---|---|---|
| Raw .svg (via <img>) | 0 B | No | Yes (CDN immutable) | Multi-color logos, flags, 3D icons, hero illustrations |
| React TSX / Vue 3 / Svelte | 0 B in RSC; tiny in CSR | Yes (currentColor + props) | Inside route chunk | Interactive buttons, navbars, design-system UI controls |
| SVG <symbol> Sprite | 0 B | Yes (currentColor + CSS vars) | Yes (same-origin file) | Glyphs repeated 15–100× across tables, feeds & menus |
| CSS Mask / Data URI | 0 B | Mask: Yes | BG: No | Inside .css bundle | Markdown external-link icons, ::before/::after, inputs |
| WebP (64–2048px) | 0 B | No | Yes | Complex filter-heavy 3D cards & modern CMS thumbnails |
| PNG / .ICO (64–2048px) | 0 B | No | Yes | HTML email clients, OpenGraph cards, PWA & legacy favicons |
Fast Three-Question Flowchart
- Does the target platform block SVG entirely (email, OpenGraph, App Store screenshot)? Export PNG or WebP from the SVG-to-PNG/WebP converter.
- Does the icon need hover/dark-mode recoloring? If NO (brand logo, flag, complex illustration), use static
<img src="...svg">. If YES, continue to Question 3. - How many times does it appear on one page? Under ~15 instances -> TSX/Vue/Svelte component; 15+ repeated instances -> <symbol> sprite; CSS-only selector -> CSS mask-image.