The Adoption Problem No One Talks About

Design systems get plenty of lip service, but the conversation usually stops at why you need one. The harder truth is what happens after launch: teams pour years into building a system, only to watch teammates ignore the guardrails and invent their own components anyway.

The real challenge isn’t creating components — it’s creating components that people actually use. In fact, it’s arguably too easy to make a component in modern design tools. Local components appear in files constantly, created by well-meaning team members who just wanted to speed up their own workflow. Nothing stops anyone from building duplicates of components that already exist in the system. If you’ve been there, you’re not alone.

“It’s a signature trait of design system teams to believe they’re moving too slow and must move faster. Actually, successful design systems move more slowly than the products they support.”

— Josh Clark, “Ship Faster by Building Design Systems Slower

The ease of creation stands in stark contrast to the difficulty of making a component that works well across an organization. What counts as “good” is subjective: every company has different requirements, design teams often can’t agree on naming conventions for even the simplest elements, and engineering teams each work in their own way. There is no universal standard. A $99 UI kit wasn’t designed for your business; you’ll have to reshape it. A polished React component your engineers found might fail accessibility checks, sending you back through QA.

Part of a Bigger System

Components don’t belong to design alone — they sit inside a system that spans engineering, brand, and marketing. Calling this work a “design system” undersells it. The work is cross-functional by nature, and labeling it with one discipline’s name can undermine collaboration and shared ownership. Everyone involved is a problem solver, regardless of title. A designer can usefully contribute to an API structure; an engineer can refine a complex form’s user flow. That’s collaboration in its purest form — no reason to make it harder by stamping one discipline’s name on cross-functional output.

The flexibility of modern design tools also sets teams up for failure. With so much freedom at hand, components proliferate faster than governance can catch up. What teams actually want from their components is a set of qualities that work together:

  • Flexible
  • Repeatable
  • Adoptable
  • Indexable
  • Logical
  • Specific

Call it the FRAILS framework for short.

Flexible and specific may sound contradictory, and to some degree they are. Yet it’s exactly this balance that most design teams are chasing. There’s a workable middle ground — but it requires deciding whether your system leans flexible or rigid, and being deliberate about that choice upfront.

This first part focuses on the first two qualities: Flexible and Repeatable. Getting those right is the foundation for everything that follows.

Flexibility Comes With Guardrails

Ask design teams what makes a component consumable, and the most common answer you’ll hear is “flexibility.” On its face, that makes sense. Reusability — the DRY principle borrowed from software engineering — is a solid foundation for any system. But flexibility in a design tool has a side effect: when it’s too easy to modify an instance, components get pushed past their intended boundaries.

Take the negative (warning) state of a form input — the red border that flags missing data. Nothing stops a designer from swapping that red for a pleasant green. That’s flexibility in its rawest form, and it often gets promoted accidentally by shipping generic components that require customization on every single use.

A diagram which illustrates semantic color meanings. Red is for negative, orange is for notice, green is for positive, blue is for informative, and accent recreated from Adobe Spectrum’s design system.
Diagram illustrating through labels the semantic color meanings for red (negative), orange (notice), green (positive), and blue (informative and accent) recreated from Adobe Spectrum’s design system. (Large preview)

The counterweight is education and communication. If certain styles are off-limits, make that visible in the component itself. Layer names can carry emoji shortcuts: a quick “please don't edit” or “you can edit this” signal. Or go further and separate components by intention entirely — ship an Input/Error, rather than a fully customizable Input.

On the left is shown a single component, one input that contains two fields (default and error); on the right, there are now two components: one is for default, the other for error.
Splitting components: one input field with a default and error state becomes two individual components. (Large preview)

The emoji naming approach works well when it’s systematic. A useful set covers the full lifecycle:

  • Components: 🚨 Deprecated, 🟠 Not ready
  • Component instances: 🔐️ Not editable, ✍️ Overwritten name
  • Layers: ✍️ Editable, 🚨 Important
  • Component properties: ◈ Type, ✍️ Edit text, 🔁️ Swap instance, 🔘 Toggle, ←️ Left, →️ Right, 🖱 Interaction, 📈 Data, ↔️ Size
An illustration that shows emoji naming conventions within components, component instances, layers, and component properties.
Emoji naming conventions within components, component instances, layers, and component properties. (Large preview)

Responsive Is a Stronger Test

Responsive design is where the flexibility ideal runs into real constraints. There is no fully native way to make a Figma component responsive in the sense that its layout direction and contents shift at defined breakpoints. You can approximate some of this with auto layout wrapping and min/max widths, but that path tends to end in a mess of magic numbers — a long list of variable values that work only under very specific circumstances and break the moment those change.

The same card is at different breakpoints: desktop (1440), tablet (768), and mobile (320). The card contains the following elements: a photo of raspberries, ‘Card Title’, ‘Card description’, and ‘Action’ button; and each element within each card is rearranged differently at different breakpoints.
A card at different breakpoints: desktop (1440), tablet (768), and mobile (320). (Large preview)

Rather than chase one hyper-flexible component that morphs from mobile to desktop, it may be simpler to ship separate components for each breakpoint. Creating more components is rarely a mistake if it improves adoption. Before deciding how to structure your library, ask a few questions:

  1. Does the team design for various screen sizes and dimensions, such as mobile and desktop web?
  2. Does the development team build for a specific platform or set of screen sizes, such as a dedicated iOS team?
  3. Do you build apps that align with native style guides, such as Material Design?
An image that shows a matrix that can help you decide whether your components should be shared or unique. It is created in the form of a table; the table header has ‘Shared Components’ and ‘Unique Components’; on the left, there is a series of questions in three rows, and there are checkboxes in the columns/rows intersections.
A matrix to help you decide whether your components should be shared or unique. (Large preview)

Library Structure Follows Answers

The answers to those questions determine whether your components live in one shared file or in several platform-specific ones. If teams build for distinct, device-specific experiences with native guidelines, keep separate component libraries. Mixing an iOS component into a web design — and pushing it to production — becomes increasingly likely when naming conventions are shared across platforms.

An illustration that shows a design system structure example within Figma. The title is ‘UI Kit’, and below are five boxes: ‘File: Foundations’, ‘File: Icons’, ‘File: ‘Global’, ‘File: iOS’, and ‘File: Android’.
A design system structure example within Figma. (Large preview)

The recommended structure, inspired by Luis Ouriach’s Figma community file “Simple design system structure,” is to maintain a global set of styles and components used across every platform, then layer on a localized set for native design work.

Get “Simple design system structure” [FigJam file / Luis Ouriach, CC-BY license]
An example mapping of library files for an iOS design project. The image is similar to the previous one: the title is ‘UI Kit’, and below are five boxes. From the first four boxes (‘File: Foundations’, ‘File: Icons’, ‘File: ‘Global’, ‘File: iOS’), there are four arrows going into another larger box at the bottom that says: ‘File: iOS App designs’. From the box ‘File: Android’, there is no arrow.
An example mapping of library files for an iOS design project. (Large preview)

For teams working in a device-agnostic manner, components can live much closer together. If your codebase isn’t agnostic yet, Mitosis — a free tool under the MIT license — compiles components written once into standard JavaScript plus frameworks like Angular, React, and Vue, eliminating redundant cross-team work.

A screenshot of a page from the Simple design system structure Figma community file, by Luis Ouriach.
The “Simple design system” Figma community file. (Large preview)

Organizing for More Than One Breakpoint

Once you accept the need for multiple components, the question becomes how to organize them. One pattern is a variant set with a property for device, size, or platform. That works for smaller systems, but complexity grows as you add states; on larger teams, splitting them apart is the better path.

A screenshot that shows the use of variants. There are two cards here that are similar to the ones found in the ‘A card at different breakpoints’ illustration. The cards contain the following elements: a photo of raspberries, ‘Card Title’, ‘Card description’, and ‘Action’ button; and each element within each card is rearranged differently for the different platforms: desktop and mobile.
Using variants for different platform types. (Large preview)

A cleaner approach for larger libraries is grouping by sections:

  1. Use pages within Figma libraries to organize components.
  2. Within each page, group each breakpoint into a section, titled by the breakpoint.
  3. Name every component by its semantic, discoverable name.
An image similar to the previous one in the list. The cards again contain the following elements: a photo of raspberries, ‘Card Title’, ‘Card description’, and an ‘Action’ button. On the left, the Desktop card layout is shown with a horizontal content arrangement, and on the right, the Mobile one with a vertical content arrangement.
Using sections for components. (Large preview)

Could variables handle these breakpoints and eliminate the need for separate components? It depends entirely on your team’s comfort level with the variable workflow. If designers and developers are fluent in it, consolidation is achievable. If not, many components are the more reliable answer.

A split-component approach also permits structural differences across breakpoints — something a variant-based system cannot offer.

Auto Layout Does the Heavy Lifting

No matter how components are grouped, auto layout applied at every level of a screen gets responsiveness very close to what HTML and CSS natively provide. That shared mental model pulls design and engineering closer together.

Auto layout and minimum width within Figma in action.

Still, variables plus auto layout only goes so far. If layout structure or typography styles diverge meaningfully between breakpoints, maintaining multiple components will serve your team better than a single, endlessly flexible one.

Repeatable

At their core, every component is repeatable. The friction around reusability emerges when we confront a component’s specificity. That specificity typically comes down to three axes:

  • Textual content: labels, titles, and other text.
  • Imagery/media: cropping, aspect ratios, and visual style.
  • Arrangement: the order of elements inside a component.

Handling Textual Content

Text overrides are frequently the first major obstacle in a design system journey. Two core practices can reduce the damage and keep overrides intact when you need to edit instances.

Let’s start with a definition, because “override preservation” is a dense phrase.

A screenshot that shows a generic input field, with a value of ‘Label’.
A generic input field. (Large preview)

Consider a basic input field. Your main component has a default text label like “Label.” That generic text is useful — it tells the designer that the content is swappable at the instance level.

Now you place that component into your design and replace “Label” with “Email address.” That swap is your override, and it works fine so far.

A screenshot that illustrates an override to the previous input field. The value now reads ‘Email address’.
Let’s change the value of “Label” to “Email address” — this is an override! (Large preview)

The trouble arrives when you need to make a structural change to the main component. Suppose the placeholder text now needs to become a label positioned above the input field. The instinct might be to create a new text element for that label. But if you do, you break the mapping between the original text element and its new location — Figma won’t know how to transfer the “Email address” override from the old element to the new one, even if the layer names look similar. Existing signed-off designs could end up broken.

A more complex illustration that shows what happens when you make a structural change and the ‘Placeholder’ becomes a ’Label’ above the input field. Top: Old component; bottom: New component.
If you make a structural change and the “Placeholder” becomes a “Label” above the input field, you create a new text element for the label, losing the mapping between your original text element and the new one. (Large preview)

Adding a text component property to every text layer is the better safeguard here, preventing data loss across files that consume the component.

An illustration that shows how a text component property is added to your text layers.
I recommend adding a text component property to your text layers. (Large preview)

As mentioned earlier, prefixes like ✍️ keep these properties scannable in the component properties panel.

Content Specificity

A more fundamental decision is how specific the default content should be.

If the answer to “will this text change frequently?” is yes, abstract the default value. A placeholder reading “[placeholder]” is a reverse-psychology nudge that prompts a designer to replace it with their local context, so the component can be interpreted broadly.

Two examples are shown. On the left is ‘Fixed content’, on the right is ‘Flexible content’. In the flexible content example (on the right), a text layer reading ’[placeholder]’ below ‘[Label]’ would prompt a designer to change it to their specific local use case.
Fixed content/Flexible content example. In the flexible content example, a text layer reading “[placeholder]” would likely prompt a designer to change it to their local use case. (Large preview)

If the answer is no, bake the fixed value directly in. Returning to the input field example, set the default label to “Email address” and move on — or create an entirely new email-address component if usage patterns justify it.

Managing Imagery and Media

Setting up a media content system raises two recurring questions:

  1. How do you assign specific media to specific components?
  2. How do you lock in aspect ratios?

Inside Figma, an image is a fill on a shape rather than a distinct content type, which affects how we manage it. There are two primary approaches:

  1. Using styles.
  2. Using component sets (variants).

First, consider the format that all assets inside Figma can take.

There are six boxes in the image. The top row is Media format: [Domain] / [Type] / [Name]; and the bottom row is Media example: Figma.com / Logo / FigJam.
The proposed media format: [Domain] / [Type] / [Name], with an example: Figma.com / Logo / FigJam. (Large preview)

In practice, treat your media assets as their own library — potentially several, if the org spans brands or product lines with different visual approaches.

A proposal for a Figma library media structure. Three file boxes on the left: Media → Global, Media → Product, Media → Marketing. Then there’s an arrow that points from these three file boxes to another box on the right, which shows ‘Pages’ at the top of it, and then there are ‘Logos, Icons, Illustrations, Images, Videos’ underneath.
A proposal for a Figma library media structure. There are three files: Media → Global, Media → Product, Media → Marketing. Within these files, the idea is to have the following page structure: Logos, Icons, Illustrations, Images, and Videos. (Large preview)

A product team’s imagery in design files looks very different from marketing materials, so split them into separate Figma libraries. Designers toggle on the library that matches their intent, keeping media appropriately scoped.

Like styles and components, media can use slash naming conventions to group assets by type.

Domain examples:

  • Company website,
  • Product,
  • Marketing,
  • Sub brand/s.

Media types:

  • Logo,
  • Icon,
  • Illustration,
  • Image,
  • Video.
A screenshot that shows four example styles. Four boxes on it, and inside each box: ‘Figma.com/Logo/Figma,’ ‘Figma.com/Icon/Variable,’ ‘Figma.com/Illustration/Components,’ ‘Figma.com/Image/Office.’
Four example styles: Figma.com/Logo/Figma, Figma.com/Icon/Variable, Figma.com/Illustration/Components, Figma.com/Image/Office. (Large preview)

Example names, using the full format:

  • Figma.com/Logo/Figma,
  • Figma.com/Icon/Variable,
  • Figma.com/Illustration/Components,
  • Figma.com/Image/Office,
  • Designsystems.com/Logo/Stripe,
  • Designsystems.com/Icon/Hamburger,
  • Designsystems.com/Illustration/Orbs,
  • Designsystems.com/Image/Modular grid.

These break down as:

  • Library: Figma.com or Designsystems.com,
  • Media type: Illustration or Logo,
  • Media name: e.g., Component libraries, Iconography.

The same structure works for video assets. Done well, this lets a team operate Figma like a mini DAM (digital asset manager), iterating with brand-approved media rather than proxy content.

“A digital asset management solution is a software solution that provides a systematic approach to efficiently storing, organizing, managing, retrieving, and distributing an organization’s digital assets. DAM functionality helps many organizations create a centralized place where they can access their media assets.”

— IBM, “What is digital asset management?

Fill Styles for Media

Fill styles aren’t limited to color — images, videos, and illustrations work just as well. Because fills are so flexible, fixed sizes or aspect ratios are essential to keep cropping predictable.

Figma’s redline “snapping” visual cue shows when the resize respects the original asset’s aspect ratio — a handy feature.

The redline “snapping” feature lets us know when the original asset’s aspect ratio is being respected as we perform a resize.

Component Sets for Fixed Aspect Ratios

It may feel counter-intuitive to treat images as components, but the approach offers much tighter control over media usage.

Images as components shines when you design against fixed aspect ratios like 16:9, 4:3, or 1:1, typically dictated by the grid. It’s less suited to flexible background fills, but ideal for logos, illustrations, and icons needing variations — say, a filled and an outline state, or different stroke weights per size.

A detailed image that shows a proposal for structuring a Figma variant component for mixed aspect ratios and sizes. The top shows the X axis (for the aspect ratios), and the left shows the Y axis (for the sizes, in pixels). A photo of a cat is being used to illustrate the different aspect ratios.
A proposal for structuring a Figma variant component for mixed aspect ratios and sizes. Along the X axis are the aspect ratios, and on the Y axis are the sizes. (Large preview)

An example is available from Figma’s community:

Fixed aspect ratio images with variants” [Figma file / Luis Ouriach, CC-BY license]

That said, don't try to hack Figma into fully responsive images. Instead, ship a predefined fixed set of sizes in a component set. It might feel limiting, but the more time spent inside Figma, the further we drift from the actual production environment. Asking “can we test this in the real product?” should be a constant reflex.

Operationally, build a component set with fixed sizes along one dimension and aspect ratios along the other. Toggle between them via the Component Properties panel, all while the media content stays preserved inside.

The approach can pair with a separate set of components just for images. Using nested instances inside variant components, you can surface every preferred image at each needed aspect ratio from every instance.

A detailed image that demonstrates how to nest a main variant component for each image type, which is then nested inside a separate variant component for the size. Again, a photo of a cat is being used in the explanation.
A demonstration of nesting a main variant component for each image type, which is then nested inside a separate variant component for the size. (Large preview)

Arrangement

Predicting rearrangement needs is the hardest part of component design. Forms are the classic problem: wrapping the whole thing as one component appears logical upfront.

The snag: when a designer needs to restructure it, you run into trouble.

A detailed image that shows a form component in two variations. On the left, we have a form with ‘full name’, ‘email address’, and a ‘sign up’ button. On the right is shown a form in the same visual style, but the fields are ‘first name’, ‘second name’, and ‘email address’; and the button after the fields is now a button group (two buttons): one button for “cancel”, the other button for “sign up”.
A form component in two variations. Left: We have a form with “full name,” “email address,” and a “sign up” button. Right: Here we have a form in the same visual style, but the fields are “first name,” “second name,” and “email address.” The button has been converted into a button group: one button for “cancel,” the other for “sign up”. (Large preview)

This challenge hits almost every component group that needs manipulation — tables, menus, lists, forms, navigation. The solution lies in defining fixed versus flexible content, a framing that keeps DRY (don’t repeat yourself) principles intact.

Maintainers naturally want one component to serve many uses without shipping an infinite number of variations. That’s DRY in a nutshell, but design tools make it awkward because they lack native control over order within a main component.

The failure mode is familiar: endless component variations of the same core component appear, all in a bid to accommodate each snowflake implementation of the library.

“‘When should we make something a component?’ is a question I’ve been fielding for years. My strong answer: right from the start. Creating things with a component-based mindset right out the gate saves countless hours — everything is a component!”

— Brad Frost, “Design system components, recipes, and snowflakes

A form might be used for logging in, registering, subscribing to a newsletter, or capturing billing info. These differ in data points and backend behavior, yet they share structural DNA — margins, heading styles, labels, and input fields. The central design problem: reduce repetition while fostering combinatorial composition.

An illustration that shows how to fix the spacing values between each element while making the combinations of components infinitely flexible. Two forms with different spacing component combinations are being shown.
When designing forms, we need to fix the spacing values between each element but make the combinations of components infinitely flexible. (Large preview)

Component slots” is a longstanding solution from the developer world that the design community is slowly adopting. Slots let maintainers ship a shell with set properties — sizing, padding, and styles — while the interior stays flexible for arrangement.

Apply that to forms: release a generic “form/wrapper” shell, then let designers assemble the login, register, newsletter, and billing forms locally as custom variants that slot inside that shell.

Figma tip: Scoped slot components

The immediate question is where such custom components live. The governance path mirrors any other component — team library or global system, depending on your structure.

A complex illustration that shows a usage graph for components. There are three main elements in the illustration. The top one shows the ‘Global component,’ the middle one ‘Domain/team component,’ and the bottom one ‘Snowflake component.’
A usage graph for components. If you need a snowflake component specific to your feature work, store it locally in the file. If it is required by your specific team or platform, you can move it into a team library. If it needs to be globally used, move it into the broader design system. (Large preview)

If a custom variant is used across multiple files, promote it up to the team-level or global library. Otherwise keep it page-local (a useful convention is labeling that group “❖ Components”).

Important: Auto layout must be used at every level, without exception, for this stacking principle to hold up.

Wrapping Up Part 1

That was a lot to process — over five thousand words, to be precise — and it’s worth stepping away from the screen before we tackle the next batch of principles. Take a break, stretch, or grab a drink.

When you’re ready, join me in Part 2, where we’ll dig deeper into the adoptable, indexable, logical, and specific components.