June 12, 2026
How to manage icon colour variants in a design system (without shipping 5 sprite files)
Why SVG sprites break at scale
SVG sprites work well for small, stable icon sets in a single colour. The problems start when you add design system requirements: dark mode, brand palettes, accessibility contrast variants, regional themes.
The standard answer is one sprite per colour variant. In practice this means:
Multiply every icon change by the number of variants. If you have 200 icons and update the chevron-right shape, that's a change in 4–8 files. Your review process touches every one of them. The more consistent you try to be, the more work each change creates.
No single source of truth. Each sprite file is an independent snapshot. There's no guarantee they stay in sync. A designer exports a corrected icon to icons-dark.svg and forgets to update icons-brand-primary.svg. Now there's an inconsistency that lives undetected for months.
Bundle size compounds quickly. An SVG sprite for 200 icons sits at roughly 460KB. Four variants: 1.8MB. Eight variants: 3.7MB. On a global site with users in low-bandwidth markets, this matters. And because sprites are typically inlined, none of it is cached.
Tooling complexity grows with every variant. Your build pipeline has to handle N files. Your Figma library has to organise N pages or N frames. Your PR templates have to remind engineers to update all N files. The process debt grows quietly.
The deeper problem is that SVG sprites were designed as a solution for a different era of the web. They predate CSS custom properties, predate design tokens as a concept, and predate the idea of a font file as infrastructure.
What COLRv1 colour fonts solve
COLRv1 is an OpenType format that embeds colour layer metadata into a font file. The key behaviour: CSS controls colour at runtime. One font file serves every theme your design system needs.
Here's what that looks like in practice:
/* Default theme — icons inherit the brand blue */
@font-face {
font-family: "MyIcons";
src: url("/fonts/my-icons.woff2") format("woff2");
}
/* Dark mode palette */
@font-palette-values --dark-mode {
font-family: MyIcons;
override-colors: 0 #E2E8F0;
}
/* Brand variant — swap to a different primary */
@font-palette-values --brand-secondary {
font-family: MyIcons;
override-colors: 0 #7C3AED;
}
/* Applying the theme */
.dark-mode .icon {
font-family: MyIcons;
font-palette: var(--dark-mode);
}
No re-export. No new sprite file. No PR that touches every variant. You add a new @font-palette-values block and the whole icon system shifts colour at runtime.
The file size comparison is stark. An SVG sprite for 200 icons: ~460KB. A COLRv1 WOFF2 for the same 200 icons: ~10KB. That's roughly 30× smaller — and it covers every colour variant you'll ever need from that single file.
For a design system team, this changes the economics of icon management fundamentally. A single font file can be cached once and reused across every product that references it.
The team workflow: a shared font repository
The file format alone doesn't solve the governance problem. You also need a workflow where multiple designers can contribute icons to the same build without creating chaos — and where one person controls what actually ships to production.
The shared font repo model works like this:
One token, one team. Every designer on the team connects to the same icon repository using a shared Figma plugin token. When anyone imports an icon frame from Figma, it goes into the same build — not a personal export, not a separate file.
Designers contribute. The lead publishes. Individual designers add or update icons through the course of their normal Figma work. When the build is ready, the design system lead reviews what changed and exports the updated WOFF2. That single export is the new source of truth.
One file deploys everywhere. Every product — web app, marketing site, internal tooling — references the same font file. When the file updates, every product gets the change. There's no "which version is production using?" question, because there's only one version.
Compare the two workflows side by side:
Old workflow (SVG sprites):
- Designer updates icon in Figma
- Designer exports SVG manually
- Designer updates
icons-light.svg,icons-dark.svg,icons-brand-primary.svg,icons-brand-secondary.svg - Engineer opens a PR touching 4 files
- Reviewer checks all 4 files for consistency
- 4 CI steps, 4 cache invalidations, 4 deploys
New workflow (shared font repo):
- Designer imports updated frame from Figma in Hue Type
- Team lead reviews and exports updated WOFF2
- Engineer deploys one file
- CSS handles every colour variant at runtime
The number of steps where things can go wrong drops from 6 to 3.
When this works (and when it doesn't)
The COLRv1 approach works in any browser shipped in the last three to four years:
- Chrome 98+ ✓
- Firefox 107+ ✓
- Safari 15.4+ ✓
- Global coverage: ~72%
If your design system still needs to support IE11 or older Android WebView, this won't work as a complete replacement. You'd need a fallback — either a legacy sprite file served conditionally, or a monochrome fallback font.
For most product teams building modern web applications in 2026, 72% global and 90%+ of active desktop browsers is sufficient. Check your analytics before deciding.
A few technical requirements for the icons themselves:
- Clean SVG structure. Each icon should be a single-layer vector path, or clearly separated layers where each layer maps to a colour slot. Embedded rasters and complex gradient meshes don't translate cleanly.
- Consistent viewBox. All icons in a shared font should share the same viewBox dimensions. Mixed sizes create optical inconsistencies in the rendered font.
- Accessibility unchanged. Colour fonts don't solve accessibility automatically. You still need
aria-labelor a visually hidden label on meaningful icons, and you still need to test colour contrast for each palette.
How to build one with Hue Type
Hue Type is a browser-based tool that converts SVG icon sets into COLRv1 WOFF2 fonts, with a shared workflow built for design teams.
The three steps:
1. Connect Figma. Install the Hue Type Figma plugin and add your team's shared token. Any designer on the team with the token can import frames directly from their Figma files — no manual SVG export required.
2. Build the font. Hue Type reads the icon layers, maps each colour to a CSS palette slot, and assembles the WOFF2. You can preview the icon set before exporting, and the CSS snippet for @font-palette-values is generated automatically.
3. Ship the WOFF2. Export the font file and deploy it to your CDN or asset pipeline. Drop the CSS snippet into your design token system. Every icon, every theme, one file.
The tool is free. Projects persist so you don't lose your build between sessions. The team lead controls the final export step — which means governance is built into the workflow, not bolted on as a separate process.
→ Try it free at huetype.sunnyallan.design
The argument for changing the workflow
SVG sprites aren't a bad technology. They're an appropriate technology for a single-colour icon set that rarely changes. Design systems in 2026 are rarely that simple.
If your team is spending engineering hours keeping N sprite files in sync — if icon updates create multi-file PRs — if there's ever any ambiguity about which sprite is the current one — the maintenance cost of the current approach is already being paid. It's just distributed invisibly across every engineer who touches it.
One font file doesn't just simplify the pipeline. It makes consistency structural. There's no "we should keep these in sync" conversation, because there's nothing to sync. There's one file. It's either deployed or it isn't.
That's not a marginal improvement. It's a different model.
Related: What is a COLR font? — the technical primer on the format this article relies on.
Try the tool: Hue Type — free, Figma-native, no account required.