Icon Components & Variants in Figma, Done Right
A lot of downloadable icon libraries — and a lot of design systems built in-house — structure their icons the same way: one component set, one variant property, every icon in the set as a value on that property. It’s the intuitive way to organize a pile of icons. Figma’s own documentation says not to do it, for reasons that get worse the bigger your library gets.
The pattern, and why it’s everywhere
It starts reasonably: you have 20 icons, you group them into one component set named “Icon,” and give it a variant property — Name=arrow-right, Name=search, Name=close, and so on. One entry in the Assets panel, every icon reachable from a single dropdown. It feels tidy.
Conceptual diagram — not a literal reproduction of the Figma interface.
What Figma’s own documentation actually says
This isn’t a stylistic opinion — it’s stated directly in Figma’s official variants documentation and its published best-practices guide. Variants exist to represent the same object in different states — a button that’s default, hovered, or disabled, all one component set. The guidance is explicit that grouping visually distinct icons into one variant set is a different, discouraged use of the feature: it quickly becomes unmanageable, and the recommended alternative is an instance-swap property instead — swapping which icon is nested, not adding another value to an icon-name variant.
The three concrete reasons it breaks
1. File performance
For Figma to offer instant switching between variants in the design panel, every variant in a set has to be rendered in the background. A 40-icon variant set means 40 renders maintained for every instance of it — weight that a set of 40 separate, independent components simply doesn’t carry, because nothing needs to pre-render sibling icons it isn’t currently showing.
2. Discoverability
Every icon in the set is buried inside one Assets panel entry. A designer can’t scroll the Assets panel and see what’s available — they have to already know the set exists, drop an instance, then open the variant property to find out what’s inside it.
3. The picker itself
Variant pickers are name lists, not visual previews. Choosing an icon becomes reading text labels one at a time instead of recognizing a shape — the opposite of how icons are meant to be used. This gets worse, not better, as icon names get more similar (chevron-up and chevron-down read nearly identically in a text list).
The model that holds up
Every icon is its own component. Variants are reserved for that one icon’s own states — most commonly color (Black/White) or style (Outline/Filled). A 40-icon library is 40 separate entries in the Assets panel, each independently swappable, each with its own small, fast variant set.
Conceptual diagram — not a literal reproduction of the Figma interface.
Naming conventions that hold up past a few dozen icons
The component name is the icon’s only identity in the Assets panel search, so it has to be both searchable and collision-proof:
- Name the object, not the file it came from —
arrow-right, noticon-24orUntitled-2. A name that describes the source export instead of the pictograph is unsearchable by the people using it. - Use a flat, consistent category prefix once you pass ~50 icons —
nav/arrow-right,action/close. Figma treats/in a component name as a folder separator in the Assets panel automatically — this is a free organizational win, not extra structure to maintain by hand. - Keep the variant property name itself boring and singular —
Color, notStyle/Color/Themecombined into one property. One property per real axis of change keeps the picker legible. - Resolve collisions before they happen — if a set has both a generic
closeand a more specificclose-circle, name them so the difference is legible without opening either —action/closeandaction/close-circle, not two things both called “close.”
Migrating a library that was built the wrong way
You don’t need to redesign anything — the icons themselves are fine, it’s the structure around them that needs to change. The mechanical steps:
- 1Detach the bloated variant set into its individual icon frames — Figma’s “Ungroup” on a component set won’t do this cleanly for a large set; exporting each variant as SVG and re-importing is usually more reliable at scale.
- 2Rebuild each icon as its own component, with its own small variant set for whatever states it actually needs (usually just color).
- 3Re-point existing instances at the new components — Figma’s “Swap instance” handles this per-instance, but at hundreds of placed instances this is the step worth budgeting real time for.
- 4Publish the updated library and let team files pick up the change through Figma’s normal library-update flow, same as any other component update.
Step 1 and 2 are exactly what re-importing the original SVG source files through VectaGrid automates — every icon becomes its own component set with a Black/White variant, which is this article’s recommended structure by default, not a special case you have to configure.
A note on accessibility handoff
One-component-per-icon has a downstream benefit past Figma itself: clean, specific component names (action/close, not Icon with a variant value) are what let an engineer map a design file directly to a meaningful aria-label or accessible name in code without guessing or asking. A single “Icon” component with 40 variant values doesn’t carry that information anywhere an engineer can see it without opening Figma and reading the currently-selected variant.
Common questions
It looks more organized in the layers panel and feels that way for the first dozen icons. Past that, it works against you in exactly the ways Figma's own documentation warns about: every variant has to render in the background for instant switching, so the file gets heavier as the set grows; and the variant picker is a text list with no visual preview, so finding "arrow-right" among 40 similarly-named entries means reading labels one at a time instead of recognizing a shape.
Skip the manual work — VectaGrid does this automatically.
Drop in a folder of SVGs and get a normalized, variant-ready component library in seconds. Free for up to 100 icons.
Questions first? Email support@mosherlabs.dev or see the full VectaGrid page.