dot-skills — Airbnb iOS SwiftUI Animations Best Practices
Opinionated, strict animation craft guide for SwiftUI iOS 26 / Swift 6.2 apps. Contains 50 rules across 8 categories, prioritized by impact. Derived from Airbnb Engineering motion patterns, Apple WWDC sessions, and Apple Human Interface Guidelines. Mandates @Equatable on every animated view, motion tokens for all spring/timing values, and design system tokens for layout.
Mandated Architecture Alignment
This skill is designed to work alongside swift-ui-architect and ios-design-system. All code examples follow the same non-negotiable constraints:
@Equatable macro on every view (Airbnb measured 15% scroll hitch reduction)
@Observable for complex animation state that involves business logic triggers
@State for view-owned animation state (toggle booleans, drag offsets)
- Design system tokens:
Spacing.xs/sm/md/lg, Radius.sm/md/lg — zero hardcoded layout numbers
- Motion tokens:
Motion.standard/responsive/playful — zero scattered spring literals
- Semantic colors:
.backgroundSurface, .accentPrimary — no raw Color literals in views
- Feature animations remain presentation-only; data/network concerns stay in Data package
Scope & Relationship to Sibling Skills
This skill is the motion layer — it teaches how to BUILD fluid, performant animations. When loaded alongside sibling skills:
| Sibling Skill |
Its Focus |
This Skill's Focus |
swift-ui-architect |
Architecture (modular MVVM-C, route shells, protocol boundaries) |
Animation architecture (motion tokens, spring selection, orchestration) |
ios-design-system |
Design system infrastructure (tokens, styles, governance) |
Motion tokens and animated component patterns |
ios-hig |
HIG compliance patterns |
Motion-specific HIG (reduce motion, spatial continuity) |
Out of scope: Designer-authored vector animations (use Lottie for After Effects exports). Complex UIKit transition controllers (see Airbnb's declarative transition framework). This skill covers programmatic SwiftUI animations only.
Clinic Architecture Contract (iOS 26 / Swift 6.2)
All guidance in this skill assumes the clinic modular MVVM-C architecture:
- Feature modules import
Domain + DesignSystem only (never Data, never sibling features)
- App target is the convergence point and owns
DependencyContainer, concrete coordinators, and Route Shell wiring
Domain stays pure Swift and defines models plus repository, *Coordinating, ErrorRouting, and AppError contracts
Data owns 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:
- Adding animations to SwiftUI views or transitions
- Building gesture-driven interactions (drag, swipe, pan)
- Connecting views with spatial transitions (expand/collapse, navigation morphs)
- Designing micro-interactions (button press, toggle, loading states)
- Making content changes feel physical (number rolls, symbol replacements)
- Choreographing multi-element animation sequences (KeyframeAnimator, PhaseAnimator)
- Defining motion tokens for a design system
- Reviewing animation code for performance, accessibility, and architecture compliance
Rule Categories by Priority
| Priority |
Category |
Impact |
Prefix |
Rules |
| 1 |
Spring Physics |
CRITICAL |
spring- |
8 |
| 2 |
Timing & Feel |
CRITICAL |
feel- |
6 |
| 3 |
Gesture Continuity |
HIGH |
gesture- |
7 |
| 4 |
Spatial Transitions |
HIGH |
spatial- |
6 |
| 5 |
Micro-interactions |
HIGH |
micro- |
6 |
| 6 |
Orchestration |
HIGH |
orch- |
5 |
| 7 |
Craft & Polish |
HIGH |
craft- |
5 |
| 8 |
Content Motion |
MEDIUM-HIGH |
content- |
5 |
Quick Reference
1. Spring Physics (CRITICAL)
spring-motion-tokens — Define motion tokens as a caseless enum for all spring presets
spring-smooth-default — Default to .smooth spring for all UI transitions
spring-snappy-responsive — Use .snappy spring for responsive interactions
spring-bouncy-celebration — Use .bouncy spring for playful and celebratory moments
spring-custom-parameters — Tune custom springs with response and dampingFraction
spring-velocity-preservation — Springs preserve velocity on interruption
spring-never-linear — Never use linear or easeInOut for interactive UI
spring-completion-chaining — Use withAnimation completion for chained sequences
2. Timing & Feel (CRITICAL)
feel-250ms-max — Keep UI animations under 250ms
feel-faster-better — Faster animations almost always feel better
feel-asymmetric-enter-exit — Use asymmetric timing for enter and exit
feel-distance-proportional — Match duration to distance traveled
feel-haptic-sync — Sync haptic feedback to visual animation keyframes
feel-stagger-timing — Stagger reveals at 30-50ms intervals
3. Gesture Continuity (HIGH)
gesture-rubber-band — Rubber band at drag boundaries
gesture-momentum-dismiss — Dismiss on velocity OR distance threshold
gesture-snap-points — Use velocity-aware snap points
gesture-interruptible — Make all gesture animations interruptible
gesture-scroll-drag-conflict — Resolve scroll and drag gesture conflicts
gesture-state-transient — Use GestureState for transient drag state
gesture-projected-landing — Project gesture velocity for natural landing position
4. Spatial Transitions (HIGH)
spatial-matched-geometry — Use matchedGeometryEffect for expand/collapse morphs
spatial-zoom-navigation — Use zoom navigation transition for collection detail (iOS 18)
spatial-transition-origin — Anchor transitions to their trigger location
spatial-hero-shared-element — Share multiple element IDs for rich hero animations
spatial-sheet-morph — Use matchedGeometryEffect for sheet presentations
spatial-tab-continuity — Maintain spatial direction in tab transitions
5. Micro-interactions (HIGH)
micro-button-press-scale — Scale buttons to 0.97 on press for tactile feedback
micro-haptic-pairing — Pair every visual state change with haptic feedback
micro-symbol-effect — Use symbolEffect for SF Symbol animations
micro-toggle-bounce — Add bounce to toggle state changes
micro-long-press-fill — Animate progressive fill for long press actions
micro-loading-phase — Use repeating spring for organic loading states
6. Orchestration (HIGH)
orch-phase-animator — Use PhaseAnimator for multi-step sequences
orch-keyframe-animator — Use KeyframeAnimator for timeline-precise motion
orch-stagger-children — Stagger child elements for orchestrated reveals
orch-coordinated-entrance — Coordinate multi-element entrances with shared trigger
orch-timeline-view — Use TimelineView for continuous repeating animations
7. Craft & Polish (HIGH)
craft-reduce-motion — Respect accessibilityReduceMotion with crossfade fallback
craft-blur-bridge — Use blur to bridge imperfect transition states
craft-drawing-group — Use drawingGroup() for Metal-backed complex animations
craft-geometry-group — Use geometryGroup() to isolate layout animation propagation
craft-transaction-debug — Use Transaction to debug and override animation behavior
8. Content Motion (MEDIUM-HIGH)
content-numeric-text — Use contentTransition(.numericText) for number changes
content-scroll-transition — Use scrollTransition for scroll-position effects
content-visual-effect — Use visualEffect for position-aware animations
content-symbol-replace — Animate symbol replacement with contentTransition
content-text-renderer — Use Text Renderer for character-level animation (iOS 18)
How to Use
Read individual reference files for detailed explanations with incorrect/correct 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 |
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: ios-animations3description: Clinic-architecture-aligned iOS animation craft guidelines for SwiftUI (iOS 26 / Swift 6.2) covering motion tokens, spring physics, gesture continuity, spatial transitions, micro-interactions, and accessibility. Enforces @Equatable on animated views and keeps animation state aligned with Domain/Data feature boundaries. Use when writing, reviewing, or refactoring SwiftUI animation code under the clinic modular MVVM-C architecture. Use when this capability is needed.4---56# dot-skills — Airbnb iOS SwiftUI Animations Best Practices78Opinionated, strict animation craft guide for SwiftUI iOS 26 / Swift 6.2 apps. Contains 50 rules across 8 categories, prioritized by impact. Derived from Airbnb Engineering motion patterns, Apple WWDC sessions, and Apple Human Interface Guidelines. Mandates @Equatable on every animated view, motion tokens for all spring/timing values, and design system tokens for layout.910## Mandated Architecture Alignment1112This skill is designed to work alongside `swift-ui-architect` and `ios-design-system`. All code examples follow the same non-negotiable constraints:1314- `@Equatable` macro on every view (Airbnb measured 15% scroll hitch reduction)15- `@Observable` for complex animation state that involves business logic triggers16- `@State` for view-owned animation state (toggle booleans, drag offsets)17- Design system tokens: `Spacing.xs/sm/md/lg`, `Radius.sm/md/lg` — zero hardcoded layout numbers18- Motion tokens: `Motion.standard/responsive/playful` — zero scattered spring literals19- Semantic colors: `.backgroundSurface`, `.accentPrimary` — no raw Color literals in views20- Feature animations remain presentation-only; data/network concerns stay in Data package2122## Scope & Relationship to Sibling Skills2324This skill is the **motion layer** — it teaches how to BUILD fluid, performant animations. When loaded alongside sibling skills:2526| Sibling Skill | Its Focus | This Skill's Focus |27|---------------|-----------|-------------------|28| `swift-ui-architect` | **Architecture** (modular MVVM-C, route shells, protocol boundaries) | **Animation architecture** (motion tokens, spring selection, orchestration) |29| `ios-design-system` | **Design system infrastructure** (tokens, styles, governance) | **Motion tokens and animated component patterns** |30| `ios-hig` | **HIG compliance** patterns | **Motion-specific HIG** (reduce motion, spatial continuity) |3132**Out of scope:** Designer-authored vector animations (use [Lottie](https://github.com/airbnb/lottie-ios) for After Effects exports). Complex UIKit transition controllers (see Airbnb's [declarative transition framework](https://medium.com/airbnb-engineering/motion-engineering-at-scale-5ffabfc878)). This skill covers programmatic SwiftUI animations only.333435## Clinic Architecture Contract (iOS 26 / Swift 6.2)3637All guidance in this skill assumes the clinic modular MVVM-C architecture:3839- Feature modules import `Domain` + `DesignSystem` only (never `Data`, never sibling features)40- App target is the convergence point and owns `DependencyContainer`, concrete coordinators, and Route Shell wiring41- `Domain` stays pure Swift and defines models plus repository, `*Coordinating`, `ErrorRouting`, and `AppError` contracts42- `Data` owns SwiftData/network/sync/retry/background I/O and implements Domain protocols43- Read/write flow defaults to stale-while-revalidate reads and optimistic queued writes44- ViewModels call repository protocols directly (no default use-case/interactor layer)4546## When to Apply4748Reference these guidelines when:49- Adding animations to SwiftUI views or transitions50- Building gesture-driven interactions (drag, swipe, pan)51- Connecting views with spatial transitions (expand/collapse, navigation morphs)52- Designing micro-interactions (button press, toggle, loading states)53- Making content changes feel physical (number rolls, symbol replacements)54- Choreographing multi-element animation sequences (KeyframeAnimator, PhaseAnimator)55- Defining motion tokens for a design system56- Reviewing animation code for performance, accessibility, and architecture compliance5758## Rule Categories by Priority5960| Priority | Category | Impact | Prefix | Rules |61|----------|----------|--------|--------|-------|62| 1 | Spring Physics | CRITICAL | `spring-` | 8 |63| 2 | Timing & Feel | CRITICAL | `feel-` | 6 |64| 3 | Gesture Continuity | HIGH | `gesture-` | 7 |65| 4 | Spatial Transitions | HIGH | `spatial-` | 6 |66| 5 | Micro-interactions | HIGH | `micro-` | 6 |67| 6 | Orchestration | HIGH | `orch-` | 5 |68| 7 | Craft & Polish | HIGH | `craft-` | 5 |69| 8 | Content Motion | MEDIUM-HIGH | `content-` | 5 |7071## Quick Reference7273### 1. Spring Physics (CRITICAL)7475- [`spring-motion-tokens`](references/spring-motion-tokens.md) — Define motion tokens as a caseless enum for all spring presets76- [`spring-smooth-default`](references/spring-smooth-default.md) — Default to .smooth spring for all UI transitions77- [`spring-snappy-responsive`](references/spring-snappy-responsive.md) — Use .snappy spring for responsive interactions78- [`spring-bouncy-celebration`](references/spring-bouncy-celebration.md) — Use .bouncy spring for playful and celebratory moments79- [`spring-custom-parameters`](references/spring-custom-parameters.md) — Tune custom springs with response and dampingFraction80- [`spring-velocity-preservation`](references/spring-velocity-preservation.md) — Springs preserve velocity on interruption81- [`spring-never-linear`](references/spring-never-linear.md) — Never use linear or easeInOut for interactive UI82- [`spring-completion-chaining`](references/spring-completion-chaining.md) — Use withAnimation completion for chained sequences8384### 2. Timing & Feel (CRITICAL)8586- [`feel-250ms-max`](references/feel-250ms-max.md) — Keep UI animations under 250ms87- [`feel-faster-better`](references/feel-faster-better.md) — Faster animations almost always feel better88- [`feel-asymmetric-enter-exit`](references/feel-asymmetric-enter-exit.md) — Use asymmetric timing for enter and exit89- [`feel-distance-proportional`](references/feel-distance-proportional.md) — Match duration to distance traveled90- [`feel-haptic-sync`](references/feel-haptic-sync.md) — Sync haptic feedback to visual animation keyframes91- [`feel-stagger-timing`](references/feel-stagger-timing.md) — Stagger reveals at 30-50ms intervals9293### 3. Gesture Continuity (HIGH)9495- [`gesture-rubber-band`](references/gesture-rubber-band.md) — Rubber band at drag boundaries96- [`gesture-momentum-dismiss`](references/gesture-momentum-dismiss.md) — Dismiss on velocity OR distance threshold97- [`gesture-snap-points`](references/gesture-snap-points.md) — Use velocity-aware snap points98- [`gesture-interruptible`](references/gesture-interruptible.md) — Make all gesture animations interruptible99- [`gesture-scroll-drag-conflict`](references/gesture-scroll-drag-conflict.md) — Resolve scroll and drag gesture conflicts100- [`gesture-state-transient`](references/gesture-state-transient.md) — Use GestureState for transient drag state101- [`gesture-projected-landing`](references/gesture-projected-landing.md) — Project gesture velocity for natural landing position102103### 4. Spatial Transitions (HIGH)104105- [`spatial-matched-geometry`](references/spatial-matched-geometry.md) — Use matchedGeometryEffect for expand/collapse morphs106- [`spatial-zoom-navigation`](references/spatial-zoom-navigation.md) — Use zoom navigation transition for collection detail (iOS 18)107- [`spatial-transition-origin`](references/spatial-transition-origin.md) — Anchor transitions to their trigger location108- [`spatial-hero-shared-element`](references/spatial-hero-shared-element.md) — Share multiple element IDs for rich hero animations109- [`spatial-sheet-morph`](references/spatial-sheet-morph.md) — Use matchedGeometryEffect for sheet presentations110- [`spatial-tab-continuity`](references/spatial-tab-continuity.md) — Maintain spatial direction in tab transitions111112### 5. Micro-interactions (HIGH)113114- [`micro-button-press-scale`](references/micro-button-press-scale.md) — Scale buttons to 0.97 on press for tactile feedback115- [`micro-haptic-pairing`](references/micro-haptic-pairing.md) — Pair every visual state change with haptic feedback116- [`micro-symbol-effect`](references/micro-symbol-effect.md) — Use symbolEffect for SF Symbol animations117- [`micro-toggle-bounce`](references/micro-toggle-bounce.md) — Add bounce to toggle state changes118- [`micro-long-press-fill`](references/micro-long-press-fill.md) — Animate progressive fill for long press actions119- [`micro-loading-phase`](references/micro-loading-phase.md) — Use repeating spring for organic loading states120121### 6. Orchestration (HIGH)122123- [`orch-phase-animator`](references/orch-phase-animator.md) — Use PhaseAnimator for multi-step sequences124- [`orch-keyframe-animator`](references/orch-keyframe-animator.md) — Use KeyframeAnimator for timeline-precise motion125- [`orch-stagger-children`](references/orch-stagger-children.md) — Stagger child elements for orchestrated reveals126- [`orch-coordinated-entrance`](references/orch-coordinated-entrance.md) — Coordinate multi-element entrances with shared trigger127- [`orch-timeline-view`](references/orch-timeline-view.md) — Use TimelineView for continuous repeating animations128129### 7. Craft & Polish (HIGH)130131- [`craft-reduce-motion`](references/craft-reduce-motion.md) — Respect accessibilityReduceMotion with crossfade fallback132- [`craft-blur-bridge`](references/craft-blur-bridge.md) — Use blur to bridge imperfect transition states133- [`craft-drawing-group`](references/craft-drawing-group.md) — Use drawingGroup() for Metal-backed complex animations134- [`craft-geometry-group`](references/craft-geometry-group.md) — Use geometryGroup() to isolate layout animation propagation135- [`craft-transaction-debug`](references/craft-transaction-debug.md) — Use Transaction to debug and override animation behavior136137### 8. Content Motion (MEDIUM-HIGH)138139- [`content-numeric-text`](references/content-numeric-text.md) — Use contentTransition(.numericText) for number changes140- [`content-scroll-transition`](references/content-scroll-transition.md) — Use scrollTransition for scroll-position effects141- [`content-visual-effect`](references/content-visual-effect.md) — Use visualEffect for position-aware animations142- [`content-symbol-replace`](references/content-symbol-replace.md) — Animate symbol replacement with contentTransition143- [`content-text-renderer`](references/content-text-renderer.md) — Use Text Renderer for character-level animation (iOS 18)144145## How to Use146147Read individual reference files for detailed explanations with incorrect/correct code examples:148149- [Section definitions](references/_sections.md) — Category structure and impact levels150- [Rule template](assets/templates/_template.md) — Template for adding new rules151152## Reference Files153154| File | Description |155|------|-------------|156| [references/_sections.md](references/_sections.md) | Category definitions and ordering |157| [assets/templates/_template.md](assets/templates/_template.md) | Template for new rules |158| [metadata.json](metadata.json) | Version and reference information |159160---161> Converted and distributed by [TomeVault](https://tomevault.io/claim/pproenca) — claim your Tome and manage your conversions.162<!-- tomevault:4.0:skill_md:2026-04-11 -->