Component library architecture
Agent skills for building and maintaining mobile design systems, tokens, and component libraries.
npx -y skills add almasumdev/awesome-mobile-design-system-agent-skills --skill component-library-architectureAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Structuring a cross-platform component library into primitives, patterns, and compositions with predictable folder layout and public API. Use this when starting or reorganizing a component library.
SKILL.md
4.8 KB, as published. Nobody here has run it
Component Library Architecture
Instructions
A mobile component library succeeds when its boundaries are obvious. Three tiers, one public surface per tier, and a strict rule that higher tiers compose lower ones — never the reverse.
1. Three Tiers
| Tier | Responsibility | Examples |
|---|---|---|
| Primitives | Atomic, single-purpose, style-driven by tokens only. | Text, Icon, Button, Surface |
| Patterns | Opinionated combinations of primitives. | Field, ListItem, SearchBar |
| Compositions | Full UI moments, often domain-aware. | EmptyState, Form, AppBar |
Rule: primitives never import patterns; patterns never import compositions.
2. Canonical Folder Layout
Each platform mirrors the same structure.
design-system/
├── tokens/
│ ├── reference/
│ ├── system/
│ └── component/
└── src/
├── primitives/
│ ├── Button/
│ │ ├── Button.kt # or .swift / .dart / .tsx
│ │ ├── ButtonTokens.kt
│ │ ├── ButtonVariants.kt
│ │ └── Button.snapshot.kt
│ └── Text/
├── patterns/
│ └── Field/
└── compositions/
└── EmptyState/
3. One Public Entry Point
Each component has exactly one exported symbol (the component) and one exported type set (its props / state enums). Internals (*Tokens, *Internal, styled children) stay package-private.
Compose:
// public
@Composable
fun Button(
onClick: () -> Unit,
label: String,
modifier: Modifier = Modifier,
size: ButtonSize = ButtonSize.Medium,
intent: ButtonIntent = ButtonIntent.Primary,
leadingIcon: @Composable (() -> Unit)? = null,
)
// internal
internal object ButtonTokens { /* ... */ }
SwiftUI:
public struct DSButton: View {
public init(_ label: String, intent: DSButtonIntent = .primary,
size: DSButtonSize = .medium, action: @escaping () -> Void) { ... }
public var body: some View { ... }
}
Flutter:
class DsButton extends StatelessWidget {
const DsButton({super.key, required this.label, required this.onPressed,
this.intent = DsButtonIntent.primary, this.size = DsButtonSize.medium});
final String label;
final VoidCallback onPressed;
final DsButtonIntent intent;
final DsButtonSize size;
}
React Native:
export type ButtonProps = { label: string; intent?: ButtonIntent; size?: ButtonSize; onPress: () => void };
export const Button: React.FC<ButtonProps> = ({ ... }) => { ... };
4. Component File Contract
Every component folder ships six things:
- The component source.
- A tokens file that resolves design tokens into component-scoped values.
- A variants file with enums/sealed classes for every axis (size, intent, state).
- Unit tests (variant prop plumbing, event handlers).
- A snapshot / golden test per variant × theme.
- A docs page or Storybook story.
5. Public API Stability
- Props are additive. Removing a prop is a major bump.
- Enums are closed — exhaustive
when/switchmust still compile for consumers. - Default values are part of the contract. Changing a default is a minor bump with a changelog entry.
6. Dependency Direction
compositions/ ──► patterns/ ──► primitives/ ──► tokens/
Enforce via module boundaries (Gradle modules on Android, Swift package targets, Dart packages, TS path mappings). A CI lint fails builds on backward edges.
7. Anti-Patterns
- One giant component (
<Card>that is also a list item, a hero, and a modal). - Primitives that import domain types (
User,OrderStatus). - Parallel component variants (
ButtonPrimary,ButtonDanger) instead of one component with variant props. - Exporting internal tokens publicly, which locks you out of refactors.
Checklist
- Three tiers (primitives, patterns, compositions) exist as separate folders/modules.
- Dependency direction is one-way and enforced by tooling.
- Each component folder contains source, tokens, variants, tests, snapshots, and docs.
- One public component + its prop types per component; internals are hidden.
- Variant enums are closed and exhaustive.
- No domain types leak into primitives or patterns.