ios-design-system
Airbnb iOS Design System Best Practices
Opinionated, strict design system engineering for SwiftUI iOS 26 / Swift 6.2 apps. Contains 50 rules across 8 categories, prioritized by impact. Derived from Airbnb's Design Language System (DLS), Airbnb Swift Style Guide, Apple Human Interface Guidelines, and WWDC sessions. Mandates @Equatable on every view, @Observable for state, and style protocols as the primary component API.
Mandated Architecture Alignment
This skill is designed to work alongside swift-ui-architect. All code examples follow the same non-negotiable constraints:
- Feature modules depend on
Domain+DesignSystem; no directDatadependency @Observablefor mutable UI state,ObservableObject/@Publishednever@Equatablemacro on every view- Style protocols as the primary component styling API (Airbnb DLS pattern)
- Asset catalog as the source of truth for color values
- Local SPM package for design system module boundary
Scope & Relationship to Sibling Skills
This skill is the infrastructure layer — it teaches how to BUILD the design system itself. When loaded alongside sibling skills:
| Sibling Skill | Its Focus | This Skill's Focus |
|---|---|---|
swift-ui-architect |
Architecture (modular MVVM-C, route shells, protocol boundaries) | Design system infrastructure (tokens, styles, governance) |
ios-design |
Using design primitives (semantic colors, typography) | Engineering the token system that provides those primitives |
ios-ui-refactor |
Auditing/fixing visual quality issues | Preventing those issues via governance and automation |
ios-hig |
HIG compliance patterns | Asset and component infrastructure that makes compliance easy |
Clinic Architecture Contract (iOS 26 / Swift 6.2)
All guidance in this skill assumes the clinic modular MVVM-C architecture:
- Feature modules import
Domain+DesignSystemonly (neverData, never sibling features) - App target is the convergence point and owns
DependencyContainer, concrete coordinators, and Route Shell wiring Domainstays pure Swift and defines models plus repository,*Coordinating,ErrorRouting, andAppErrorcontractsDataowns SwiftData/network/sync/retry/background I/O and implements Domain protocols- Read/write flow defaults to stale-while-revalidate reads and optimistic queued writes
- ViewModels call repository protocols directly (no default use-case/interactor layer)
When to Apply
Reference these guidelines when:
- Setting up a design system for a new iOS app
- Building token architecture (colors, typography, spacing, sizing)
- Creating reusable component styles (ButtonStyle, LabelStyle, custom DLS protocols)
- Organizing asset catalogs (colors, images, icons)
- Migrating from ad-hoc styles to a governed token system
- Preventing style drift and enforcing consistency via automation
- Building theming infrastructure for whitelabel or multi-brand apps
- Reviewing PRs for ungoverned colors, hardcoded values, or shadow tokens
Rule Categories by Priority
| Priority | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | Token Architecture | CRITICAL | token- |
6 |
| 2 | Color System Engineering | CRITICAL | color- |
7 |
| 3 | Component Style Library | CRITICAL | style- |
10 |
| 4 | Typography Scale | HIGH | type- |
5 |
| 5 | Spacing & Sizing System | HIGH | space- |
5 |
| 6 | Consistency & Governance | HIGH | govern- |
7 |
| 7 | Asset Management | MEDIUM-HIGH | asset- |
5 |
| 8 | Theme & Brand Infrastructure | MEDIUM | theme- |
5 |
Quick Reference
1. Token Architecture (CRITICAL)
token-three-layer-hierarchy- Use Raw → Semantic → Component token layerstoken-enum-over-struct- Use caseless enums for token namespacestoken-single-file-per-domain- One token file per design domaintoken-shapestyle-extensions- Extend ShapeStyle for dot-syntax colorstoken-asset-catalog-source- Source color tokens from asset catalogtoken-avoid-over-abstraction- Avoid over-abstracting beyond three layers
2. Color System Engineering (CRITICAL)
color-organized-xcassets- Organize color assets with folder groups by rolecolor-complete-pairs- Define both appearances for every custom colorcolor-limit-palette- Limit custom colors to under 20 semantic tokenscolor-no-hex-in-views- Never use Color literals or hex in view codecolor-system-first- Prefer system colors before custom tokenscolor-tint-not-brand-everywhere- Set brand color as app tint, don't scatter itcolor-audit-script- Audit for ungoverned colors with a build script
3. Component Style Library (CRITICAL)
style-dls-protocol-pattern- Define custom style protocols for complex DLS componentsstyle-equatable-views- Apply @Equatable to every design system viewstyle-accessibility-first- Build accessibility into style protocols, not individual viewsstyle-protocol-over-wrapper- Use Style protocols instead of wrapper viewsstyle-static-member-syntax- Provide static member syntax for custom stylesstyle-environment-awareness- Make styles responsive to environment valuesstyle-view-for-containers-modifier-for-styling- Views for containers, modifiers for stylingstyle-catalog-file- One style catalog file per component typestyle-configuration-over-parameters- Prefer configuration structs over many parametersstyle-preview-catalog- Create a preview catalog for all styles
4. Typography Scale (HIGH)
type-scale-enum- Define a type scale enum wrapping system stylestype-system-styles-first- Use system text styles before custom onestype-custom-font-registration- Register custom fonts with a centralized extensiontype-max-styles-per-screen- Limit typography variations to 3-4 per screentype-avoid-font-design-mixing- Use one font design per app
5. Spacing & Sizing System (HIGH)
space-token-enum- Define spacing tokens as a caseless enumspace-radius-tokens- Define corner radius tokens by component typespace-no-magic-numbers- Zero hardcoded numbers in view layout codespace-insets-pattern- Use EdgeInsets constants for composite paddingspace-size-tokens- Define size tokens for common dimensions
6. Consistency & Governance (HIGH)
govern-naming-conventions- Enforce consistent naming conventions across all tokensgovern-spm-package-boundary- Isolate the design system as a local SPM packagegovern-single-source-of-truth- Every visual value has one definition pointgovern-lint-for-tokens- Use SwiftLint rules to enforce token usagegovern-design-system-directory- Isolate tokens in a dedicated directorygovern-migration-incremental- Migrate to tokens incrementallygovern-prevent-local-tokens- Prevent feature modules from defining local tokens
7. Asset Management (MEDIUM-HIGH)
asset-separate-catalogs- Separate asset catalogs for colors, images, iconsasset-sf-symbols-first- Use SF Symbols before custom iconsasset-icon-export-format- Use PDF/SVG vectors, never multiple PNGsasset-image-optimization- Use compression and on-demand resourcesasset-naming-convention- Consistent naming convention for all assets
8. Theme & Brand Infrastructure (MEDIUM)
theme-environment-key- Use EnvironmentKey for theme propagationtheme-dont-over-theme- Avoid building a theme system unless neededtheme-tint-for-brand- Use .tint() as primary brand expressiontheme-light-dark-only- Use ColorScheme for light/dark, not custom themingtheme-brand-layer-separation- Separate brand identity from system mechanics
How to Use
Read individual reference files for detailed explanations and code examples:
- Section definitions - Category structure and impact levels
- Rule template - Template for adding new rules
Reference Files
| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
| metadata.json | Version and reference information |