Learn how professional design systems organize component libraries in Figma — naming conventions, component hierarchy, variant architecture, and how these decisions map directly to your CSS and React component structure.
Professional design systems in Figma follow a component library architecture that mirrors good code architecture: foundations define raw values, primitives are the smallest reusable units, and patterns are complex assemblies of primitives. Understanding this architecture means you can navigate any well-organized Figma file efficiently and know exactly where to look for any component.
This lesson covers how design system component libraries are organized, the naming conventions that make them navigable, and how the Figma library structure should drive your CSS and React component architecture.
Professional Figma libraries organize components into three pages:
Page 1 — Foundations:
Page 2 — Components (Primitives/Atoms):
Page 3 — Patterns (Molecules/Organisms):
The tier system in CSS:
1/* Foundations — CSS custom properties */
2/* src/styles/tokens.css */
3:root {
4 --color-brand-primary: hsl(220, 90%, 56%);
5 --space-4: 1rem;
6 --radius-md: 0.5rem;
7 --shadow-card: 0 1px 3px rgb(0 0 0 / 0.04);
8}
9
10/* Primitives/Atoms — individual component CSS */
11/* src/components/Button/button.css */
12.btn { /* Button primitive */ }
13
14/* src/components/Badge/badge.css */
15.badge { /* Badge primitive */ }
16
17/* Patterns/Molecules — composed of primitives */
18/* src/components/CourseCard/course-card.css */
19.course-card { /* uses .badge and .btn internally */ }React file structure mirroring Figma library:
1src/
2 styles/
3 tokens.css (Foundations)
4 reset.css
5 typography.css
6 components/
7 atoms/
8 Button/
9 Badge/
10 Input/
11 Avatar/
12 molecules/
13 Card/
14 FormField/
15 NavItem/
16 organisms/
17 Navigation/
18 Modal/
19 PricingTable/
20 CourseCard/Figma component names follow a hierarchy that should map directly to your CSS class and component naming:
Figma naming pattern: Category/Name/Variant/Size/State
Examples:
CSS architecture matching Figma naming:
1/* Component file: button.css */
2/* Mirrors: Button/* Figma component group */
3
4/* Base — applies to all buttons */
5.btn {
6 display: inline-flex;
7 align-items: center;
8 justify-content: center;
9 gap: var(--space-2);
10 padding: var(--space-3) var(--space-6);
11 border-radius: var(--radius-md);
12 font-weight: 600;
13 font-family: inherit;
14 cursor: pointer;
15 border: 1.5px solid transparent;
16 transition: 150ms ease;
17 text-decoration: none;
18 white-space: nowrap;
19 line-height: 1;
20}
21
22/* Variant: Primary — Button/Primary */
23.btn-primary {
24 background: var(--color-action-primary);
25 color: white;
26 border-color: var(--color-action-primary);
27}
28.btn-primary:hover { background: var(--color-action-hover); border-color: var(--color-action-hover); }
29.btn-primary:active { background: var(--color-action-active); }
30
31/* Variant: Secondary — Button/Secondary */
32.btn-secondary {
33 background: white;
34 color: var(--color-action-primary);
35 border-color: var(--color-action-primary);
36}
37.btn-secondary:hover { background: var(--color-action-subtle); }
38
39/* Variant: Ghost — Button/Ghost */
40.btn-ghost {
41 background: transparent;
42 color: var(--color-text-secondary);
43 border-color: transparent;
44}
45.btn-ghost:hover { background: var(--color-surface-alt); color: var(--color-text-primary); }
46
47/* Variant: Danger — Button/Danger */
48.btn-danger {
49 background: white;
50 color: var(--color-danger);
51 border-color: var(--color-danger);
52}
53.btn-danger:hover { background: var(--color-danger-subtle); }
54
55/* Size: Small — Button/*/Small */
56.btn-sm {
57 padding: var(--space-2) var(--space-4);
58 font-size: 0.875rem;
59 border-radius: var(--radius-sm);
60}
61
62/* Size: Large — Button/*/Large */
63.btn-lg {
64 padding: var(--space-4) var(--space-8);
65 font-size: 1.0625rem;
66 border-radius: var(--radius-lg);
67}
68
69/* State: Disabled — all variants */
70.btn[disabled], .btn[aria-disabled='true'] {
71 opacity: 0.4;
72 cursor: not-allowed;
73 pointer-events: none;
74}
75
76/* State: Loading */
77.btn[aria-busy='true'] {
78 cursor: wait;
79 pointer-events: none;
80 position: relative;
81 color: transparent;
82}
83.btn[aria-busy='true']::after {
84 content: '';
85 position: absolute;
86 inset: 0;
87 margin: auto;
88 width: 1rem;
89 height: 1rem;
90 border: 2px solid currentColor;
91 border-top-color: transparent;
92 border-radius: 50%;
93 animation: btn-spin 600ms linear infinite;
94 color: white;
95}
96@keyframes btn-spin { to { transform: rotate(360deg); } }Brad Frost's Atomic Design methodology — atoms, molecules, organisms, templates, pages — is the most common organizing principle for Figma component libraries.
Atoms: the smallest indivisible components
Molecules: 2-5 atoms combined
Organisms: complex sections
Component dependency tracking in CSS:
1/* Atom: Badge — no dependencies */
2.badge { /* fully self-contained */ }
3
4/* Molecule: CourseCard — depends on Badge, Button atoms */
5/* src/components/CourseCard/course-card.css */
6/* Import order matters — atoms must load before molecules */
7
8.course-card { /* layout for the card shell */ }
9.course-card .badge {
10 /* Override atom padding in card context if needed */
11 /* Minimize overrides — if you override often, the atom needs a variant */
12}
13.course-card .btn {
14 /* Override atom for full-width CTA in card */
15 width: 100%;
16 display: flex;
17}Well-maintained Figma component libraries include documentation frames alongside components: usage notes, do/don't examples, responsive behavior descriptions, and accessibility notes.
Reading component documentation in Figma:
Typical documentation insights and their CSS implications:
'Do not stack more than 2 primary buttons on the same page'
→ CSS: only one .btn-primary per screen — structural constraint, not a CSS rule
'Badge text must not exceed 12 characters'
→ CSS: .badge { max-width: 8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
'Icon-only buttons must have a tooltip on hover'
→ HTML: always include aria-label; CSS: position relative for tooltip
'Card image must always be 16:9'
→ CSS: .course-card-thumb { aspect-ratio: 16/9; overflow: hidden; }
→ IMG: always provide explicit width and height
'Form error message must appear below the input, never to the side'
→ CSS: .form-group { display: flex; flex-direction: column; } — never flex-direction: row
'Minimum touch target size: 44x44px'
→ CSS: .btn { min-width: 2.75rem; min-height: 2.75rem; } on icon-only buttons
1/* Minimum touch target enforcement (from component docs) */
2.icon-btn {
3 min-width: 2.75rem; /* 44px minimum touch target */
4 min-height: 2.75rem;
5 display: inline-flex;
6 align-items: center;
7 justify-content: center;
8 border-radius: var(--radius-md);
9 border: none;
10 background: transparent;
11 cursor: pointer;
12 color: var(--color-text-secondary);
13 transition: background-color 150ms ease, color 150ms ease;
14}
15.icon-btn:hover { background: var(--color-surface-alt); color: var(--color-text-primary); }
16.icon-btn:focus-visible {
17 outline: 2px solid var(--color-action-primary);
18 outline-offset: 2px;
19}A complete CSS architecture (tokens → atoms → molecules) that mirrors the three-tier Figma component library structure, with each file corresponding to a Figma library page.
1/*
2FIGMA LIBRARY STRUCTURE:
3Page 1: Foundations (tokens)
4Page 2: Components (Button, Badge, Input, Avatar)
5Page 3: Patterns (CourseCard, FormField, Navigation)
6
7CORRESPONDING CSS FILE STRUCTURE:
8 src/styles/tokens.css (Foundations)
9 src/styles/reset.css (Base)
10 src/components/atoms/button.css
11 src/components/atoms/badge.css
12 src/components/atoms/input.css
13 src/components/molecules/course-card.css
14*/
15
16/* ==========================================
17 tokens.css — Figma: Foundations page
18 ========================================== */
19:root {
20 /* Color primitives */
21 --prim-blue-500: hsl(220, 90%, 56%);
22 --prim-blue-600: hsl(220, 90%, 46%);
23 --prim-green-600: hsl(142, 72%, 35%);
24 --prim-green-50: hsl(142, 72%, 95%);
25 --prim-gray-0: #ffffff;
26 --prim-gray-50: hsl(220, 20%, 97%);
27 --prim-gray-200: hsl(220, 16%, 90%);
28 --prim-gray-400: hsl(220, 12%, 62%);
29 --prim-gray-600: hsl(220, 16%, 40%);
30 --prim-gray-900: hsl(220, 30%, 10%);
31 /* Color semantics */
32 --color-action-primary: var(--prim-blue-500);
33 --color-action-hover: var(--prim-blue-600);
34 --color-action-subtle: hsl(220, 100%, 97%);
35 --color-success: var(--prim-green-600);
36 --color-success-subtle: var(--prim-green-50);
37 --color-surface: var(--prim-gray-0);
38 --color-surface-alt: var(--prim-gray-50);
39 --color-border: var(--prim-gray-200);
40 --color-text-primary: var(--prim-gray-900);
41 --color-text-secondary: var(--prim-gray-600);
42 --color-text-muted: var(--prim-gray-400);
43 /* Spacing */
44 --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem;
45 --space-4: 1rem; --space-5: 1.25rem; --space-6: 1.5rem;
46 --space-8: 2rem;
47 /* Radius */
48 --radius-sm: 0.375rem; --radius-md: 0.5rem;
49 --radius-lg: 0.75rem; --radius-pill: 9999px;
50 /* Shadows */
51 --shadow-card: 0 1px 3px rgb(0 0 0 / 0.04), 0 1px 2px rgb(0 0 0 / 0.03);
52 --shadow-hover: 0 4px 12px rgb(0 0 0 / 0.08);
53}
54
55/* ==========================================
56 button.css — Figma: Components/Button
57 ========================================== */
58.btn {
59 display: inline-flex; align-items: center; justify-content: center;
60 gap: var(--space-2); padding: var(--space-3) var(--space-6);
61 border-radius: var(--radius-md); font-size: 0.9375rem; font-weight: 600;
62 font-family: inherit; cursor: pointer; border: 1.5px solid transparent;
63 transition: 150ms ease; text-decoration: none; white-space: nowrap;
64}
65.btn-primary { background: var(--color-action-primary); color: white;
66 border-color: var(--color-action-primary); }
67.btn-primary:hover { background: var(--color-action-hover); border-color: var(--color-action-hover); }
68.btn-secondary { background: var(--color-surface); color: var(--color-action-primary);
69 border-color: var(--color-action-primary); }
70.btn-secondary:hover { background: var(--color-action-subtle); }
71.btn[disabled] { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
72
73/* ==========================================
74 badge.css — Figma: Components/Badge
75 ========================================== */
76.badge {
77 display: inline-flex; align-items: center;
78 padding: 0.1875rem 0.5rem; border-radius: var(--radius-pill);
79 font-size: 0.6875rem; font-weight: 700;
80 text-transform: uppercase; letter-spacing: 0.08em;
81 white-space: nowrap;
82}
83.badge-beginner { background: var(--color-success-subtle); color: var(--color-success); }
84
85/* ==========================================
86 course-card.css — Figma: Patterns/CourseCard
87 Uses: .badge, .btn atoms
88 ========================================== */
89.course-card {
90 display: flex; flex-direction: column;
91 background: var(--color-surface);
92 border: 1px solid var(--color-border);
93 border-radius: var(--radius-lg);
94 box-shadow: var(--shadow-card);
95 overflow: hidden;
96 transition: box-shadow 200ms ease, border-color 200ms ease;
97}
98.course-card:hover {
99 box-shadow: var(--shadow-hover);
100 border-color: hsl(220 90% 56% / 0.3);
101}
102.course-card-thumb {
103 aspect-ratio: 16/9; overflow: hidden; flex-shrink: 0;
104 background: var(--color-surface-alt);
105}
106.course-card-thumb img { width: 100%; height: 100%; object-fit: cover; }
107.course-card-body {
108 padding: var(--space-5); display: flex; flex-direction: column;
109 gap: var(--space-3); flex: 1;
110}
111.course-card-title {
112 font-size: 1rem; font-weight: 700; color: var(--color-text-primary);
113 margin: 0; line-height: 1.4;
114 display: -webkit-box; -webkit-line-clamp: 2;
115 -webkit-box-orient: vertical; overflow: hidden;
116}
117.course-card-meta { font-size: 0.8125rem; color: var(--color-text-muted); margin: 0; }
118/* Molecule overrides atom for full-width CTA */
119.course-card .btn { width: 100%; display: flex; margin-top: auto; }The CSS file structure mirrors the Figma library pages: tokens.css corresponds to the Foundations page (primitive + semantic tokens), button.css corresponds to Components/Button (self-contained atom), badge.css corresponds to Components/Badge (self-contained atom), and course-card.css corresponds to Patterns/CourseCard (molecule that uses badge and btn atoms). The molecule overrides the .btn to be full-width (display: flex; width: 100%) — this is a legitimate context-specific override, not a violation of the atom. The .course-card .btn selector has higher specificity than .btn alone, following CSS specificity rules intentionally.
The next lesson covers building a design system in Figma — creating a reusable component library from scratch, organizing pages, and establishing the token and component architecture that scales.
Your progress is saved in this browser, on this device only.