A component with heart icon component. Actually, it’s a heart icon glyph as content. The difference matters.
When working in Figma, a heart icon presents as a reusable component instance inside a FavoriteButton component. In many design systems, the heart is not really a component, per se. Instead, it’s more like named content, similar to the text and images flowed into a rendered design.
Tooling downstream from Figma treat icons differently, deliberately. Specs detect glyphs as primitive content so as to evaluate specific styles like fillColor. Generators scan files to process glyph assets separate from UI components: extract the art, convert to SVGs, and expose as a catalog referenced by web, iOS and Android code libraries. Icons deserve special treatment. I’ve always wondered why Figma doesn’t handle icons separately as a special, foundational part of a design system.
Yet, just because Figma doesn’t treat icons as a first-class object doesn’t mean Figma can’t carry the intent. System designers have made and named icons deliberately in Figma for years. These practices make icons visible and legible via conventions to downstream consumers, humans and agents alike. What’s new is deciding them, writing them down, and building scripted pipelines that depend on them rather than leaking via inference along the way.
This post covers what conventions do, where they live, and what they cost. Three of the most important – icons, subcomponents and images – are explored in depth.
Extended Figma Conventions
The “Naming is hard” quote has been a design system trope for decades. It’s about naming things: a Pill vs Tag vs Chip vs Badge.
Extending Figma using conventions is one level deeper. It’s about naming what’s happening in the design system’s model when the surface doesn’t: what kind of thing is this, what is it a part of, what does it mean? The hard part is no longer naming the thing; instead, it was naming the place on am implementation’s surface where a model applies meaning.
I recently refactored my specs’ settings to consolidate Figma authoring conventions in one place. The conventions aren’t implicit, invisible, buried in the code or scattered everywhere. Instead, they are visibly collected in config/conventions/figma.yaml. As I viewed them isolated to this intentional file, I had a moment. “Yes, that’s it. These are the most important rules of how we author design system intent where Figma doesn’t carry the model natively!”
naming: SENTENCE
glyphs:
match: DS Icon asset / {i}
images:
backgroundImage: true
match: DE Image
sourceProps: [Image source]
subcomponents:
scope: PAGE
match: ['{C} / {S}', '{C} / Subfolder / {S}']
exclude: ['{C} / Examples / {S}']
instanceExamples:
scope: PAGE
parentNames: [Examples]
slotConstraints: true
inferNumberProps: true
codeOnlyProps:
match: Code only props
These settings are picked up by the specs-from-figma transformer, which extracts and transforms data from Figma into a spec. The Specs 2 plugin exposes these conventions commensurately within its settings panel.
Conventions rely on names across many existing Figma surfaces:
Component asset names for glyphs, images and subcomponents
Instance names for ready-made
instanceExamplesLayer names, such as code only props.
Prop names, such as where
image sourceis a type of contentProp values, such as if a prop’s type:number should be inferred from the default
Example: Icon glyphs
An icon glyph isn’t a component, it’s content. Sure, there may also be formal components called DE Icon, DE Icon button, and DE Favorite button each potentially carrying glyphs as content. But glyphs themselves are simple: a named vector asset with a fill and sized with intent.
Figma’s asset has one category: component asset. A glyph (content) and button (component) are the same thing until you say otherwise. As a result, a tool scanning your Figma file can’t tell your icon library from your component library. Worse, invalid icon names leak and silently fail in components, extraction requires disjoint tools, and teams grapple with communicating what icon changed when.
Therefore, name icons conventionally, prepending a namespace (like DE Icon asset) to a name (like heart). While namespacing an icon library impacts 100s of assets, it’s a convention that flows smoothly via published updates.
A namespace and / buys a lot. Specs detect, evaluate, style and track icons distinctively. Library scans can isolate icons, evaluate vectors, and generate catalogs of SVGs. Downstream scripts land icons in a specific place (like an assets/icons/ folder), wire them into components (like DE Icon button), check if a name is valid, and watch for changes.
For more on icon glyphs and specs, read the guide and setting convention.
Example: Subcomponents
An Action list component doesn’t just contain any children. It can contain distinctive Item, Group, and Group heading. Each Action list / Item contains a Start visual and End visual with distinctive prop signatures. All are composed flexibly in what becomes a deep hierarchy. And none should be used anywhere else.
Yet, Figma doesn’t know this. Instead, it’s just a hierarchy of nested component assets. In Figma, there’s no reason you couldn’t nest a Button as an Action list child, or place an Action list / Item start visual in a Card composition because, why not? Figma will let you anyway – since conventions record relationships but don’t police them. That’s what linters are for. The subcomponent relationship still matters, and nothing but the name can carry it.
Therefore, a subcomponents convention matches one or more naming patterns to establish this intentionally more specific and closed relationship. For example {C} / {S} means that Action list (the {C}) as a first-class component will collect a range of subcomponents:
Action list / HeadingAction list / Group headingAction list / GroupAction list / ItemAction list / Item start visualAction list / Item end visual
Additionally, other assets like a ready-made example may also start with Action list / Examples / Settings list and as a result need to be excluded from the set by an opposing match rule.
Specifications colocate subcomponents nested in the main component, such as:
actionList:
title: DE Action list
props:
...
anatomy:
...
subcomponents:
heading:
title: DE Action list / heading
props:
...
anatomy:
...
groupHeading:
group:
item:
itemStartVisual:
itemEndVisual:Downstream, an Action list's React generated code is similarly organized:
react/
src/
DeActionList/
Group/
GroupHeading/
Heading/
DeActionListHeading.contract.ts
DeActionListHeading.metadata.ts
DeActionListHeading.scaffold.tsx
DeActionListHeading.stories.tsx
DeActionListHeading.styles.css
Item/
ItemStartVisual/
ItemEndVisual/
DeActionList.contract.ts
DeActionList.metadata.ts
DeActionList.scaffold.tsx
DeActionList.stories.tsx
DeActionList.styles.cssAdditional conventions pick up authoring preferences, such as when subcomponents may be NESTED or solely composed (thus detected on the PAGE). The page itself holds the structure, not just a canvas of styled layers. Where an asset sits and what it’s called carry real weight, and adopting conventions forces decisions. Here, the convention suggests strongly “Include subcomponents on the same page as the main asset.” If your file is more loosely organized, that requires change.
For more on subcomponent specs, read the guide and setting convention.
Example: Images
Images are a tough one. Like glyphs, images are content, often reused intentionally across a design system library less for actual production and more for prototyping and communicating system concepts.
Yet, in Figma, images are a fill. This is the same construct where gradients, colors, and patterns go. It works, always felt a little strange, and designers like me have adapted. In design systems I work with, images often surface via either a DE Image component (with props for source and reserved aspectRatios) or flowing images through a prop to populate a background of an avatar, card or hero.
In Figma, there’s no named source property, nothing to pass; instead, click into nested layers, find the right one, and … paste the image as a fill. Not. The. Same. That doesn’t mean we can’t model our authoring behavior consistently to achieve the same outcome.
The convention is more complicated, however. System authors need to identify:
The dedicated component, if it exists (like
DE Image)Whether to also process composed concepts for “custom background fills”
backgroundImage).The conventional prop name (like
source,imageSourceorsrc) that carries the content of not justDE Imagebut also other components likeDE Avatar.
Once formalized, image handling opens up flowing intent through structure like:
Routing images through component props predictably.
Extracting images across a library with a
generate —get-imagescommand.Storing images you can point at via an
$imagereference.Improving docs, stories and test cases with images as example content.
Impacting composed page concepts via easy-to-integrate images.
Images are more complicated to set up. Conventions constrain too: the source prop is opinionated across components, and you only get one. Starting out, you may declare the component, leave backgroundImage on, and see how specs flow. If your design system doesn’t have a formal image component, this moment may be a reason to build one. It invokes useful questions, like props, features, and Figma peccadillos you need to deal with. Taking on conventions will often back you into decisions – aspect ratios, accessibility labels, fit – you didn’t know you needed or didn’t have a surface to use.
For more on images specs, read the guide and settings convention.
Drawbacks
The conventions illustrated in examples carry outsize benefits, but at a cost.
Names can be overloaded and brittle
Conventions aren’t perfect, and come with tradeoffs. From a technical perspective, relying on naming conventions for implying structure is weak because:
A name starts doing multiple jobs.
Action list / Item start visualis now carrying identity, category, hierarchy and membership in a single string value. Nothing separates those meanings, such as an official “You belong to…”Action list) or “You are only a child of…” (Item).Matches are on names, not references. Rename the
Action listparent and suddenly theItem start visualsilently detaches. The asset still exists, still nests, still looks right in the page. But semantically, it’s disconnected.Matching can’t derive intent from shape.
Action list / Examples / Settingscarries an example,Action list / Itemdefines a component, both shaped as{C} / {S}. Including anexcludematching pattern is evidence that convention setting can be brittle.
Authored can fail silently
Just because you established conventions doesn’t mean you’ve authored that way. Every convention described in figma.yaml names parts that can fail silently when authored poorly. Plus, conventions documented don’t mean conventions read and understood, by either a human or agent.
An icon got renamed outside the namespace? It never makes it to the
assets/icons/catalog.A stray subcomponent that lacks the precise main component’s name? It never gets generated as a spec or worse, shows up in the general space and adopted by teams out of context.
An image conveys with a component asset, unbound to a properly named
sourceprop? Suddenly it’s shipping as default content into production.
Layers, props and bindings named and applied wrong aren’t errors. They’re omissions, and they don’t announce themselves. Authoring with discipline is hard. Guardrails require work to implement and enforce. Linting tools and skills help, applying rules and heuristics to detect when an authored surface went sideways.
These challenges are unique to neither conventions nor Figma. Every surface you coordinate carries this, and conventions enable you to see it happening.
Promoting conventions into native features
Even in the past year, conventions have shifted into Figma’s model directly. I had the privilege of working with Figma on their emerging slot component, culminating in my talk at Schema 2025. Numerous times, I imparted how often my team didn’t want just slots, but also to constrain slots with rules: minimum items, maximum items and what instances were permissible inside, particularly for repeating items.
Lo and behold, Figma launched those SLOT prop features natively in a fast follow months later. It felt rewarding to have influenced a platform in a small way. It felt way more relieving to strip out our convention-abiding hack for slick, native tooling. Figma now holds the model so that others can read it directly.
Conventions aren’t something to hold loosely. Instead, you are writing down parts of your system the tool can’t hold, and the ones that turn out to be real sometimes stop being yours to hold at all.










Time to study! So much detail and knowledge, will work through this bit by bit to improve setup. Thanks so much for the work and sharing!