Design System Problems

iOS Design Tokens

January 15, 2026 • 5 min read

iOS Design Tokens

iOS design tokens bring systematic design values to iOS application development through Swift-native formats. Implementing tokens for iOS requires understanding UIKit and SwiftUI differences, Swift type systems, and how token pipelines generate appropriate outputs. Effective iOS token implementation enables consistent styling while embracing Swift idioms.

What Are iOS Design Tokens

iOS design tokens are design values stored in Swift code that iOS applications can reference with full type safety. Unlike CSS-based web tokens, iOS tokens exist as Swift constants, computed properties, or SwiftUI modifiers that integrate naturally with iOS development patterns.

Token transformation pipelines generate Swift files from platform-agnostic token definitions. The same source tokens that produce CSS custom properties also produce UIColor constants, CGFloat spacing values, and UIFont definitions for iOS.

How iOS Design Tokens Work

Token pipelines generate Swift files with strongly typed values:

import UIKit
import SwiftUI

public struct Tokens {
  public struct Color {
    public static let primary = UIColor(red: 0.231, green: 0.510, blue: 0.965, alpha: 1.0)
    public static let backgroundDefault = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
    public static let textPrimary = UIColor(red: 0.090, green: 0.090, blue: 0.090, alpha: 1.0)
  }

  public struct Spacing {
    public static let sm: CGFloat = 8
    public static let md: CGFloat = 16
    public static let lg: CGFloat = 24
  }

  public struct Typography {
    public static let bodyMd = UIFont.systemFont(ofSize: 16, weight: .regular)
    public static let headingLg = UIFont.systemFont(ofSize: 24, weight: .bold)
  }
}

UIKit applications reference these constants:

let button = UIButton()
button.backgroundColor = Tokens.Color.primary
button.titleLabel?.font = Tokens.Typography.bodyMd
button.contentEdgeInsets = UIEdgeInsets(
  top: Tokens.Spacing.md,
  left: Tokens.Spacing.lg,
  bottom: Tokens.Spacing.md,
  right: Tokens.Spacing.lg
)

SwiftUI tokens may include Color extensions for direct SwiftUI usage:

extension Color {
  static let tokenPrimary = Color(Tokens.Color.primary)
  static let tokenBackground = Color(Tokens.Color.backgroundDefault)
}

struct MyButton: View {
  var body: some View {
    Button("Click me") {}
      .padding(.horizontal, Tokens.Spacing.lg)
      .padding(.vertical, Tokens.Spacing.md)
      .background(Color.tokenPrimary)
  }
}

Key Considerations

Common Questions

How should theming work on iOS?

iOS theming approaches differ from web-based runtime CSS variable switching. Since Swift constants are compile-time values, runtime theming requires different strategies.

Trait-based theming uses iOS trait collections to select colors:

extension UIColor {
  static let primary = UIColor { traitCollection in
    switch traitCollection.userInterfaceStyle {
    case .dark:
      return UIColor(red: 0.376, green: 0.647, blue: 0.996, alpha: 1.0)
    default:
      return UIColor(red: 0.231, green: 0.510, blue: 0.965, alpha: 1.0)
    }
  }
}

This approach leverages iOS’s native dark mode support, automatically updating when system appearance changes.

SwiftUI Environment enables component-level theming:

struct Theme {
  var primary: Color
  var background: Color
  var text: Color

  static let light = Theme(
    primary: Color.tokenPrimary,
    background: Color.tokenBackground,
    text: Color.tokenText
  )

  static let dark = Theme(
    primary: Color.tokenPrimaryDark,
    background: Color.tokenBackgroundDark,
    text: Color.tokenTextDark
  )
}

struct ThemeKey: EnvironmentKey {
  static let defaultValue = Theme.light
}

extension EnvironmentValues {
  var theme: Theme {
    get { self[ThemeKey.self] }
    set { self[ThemeKey.self] = newValue }
  }
}

Components access the theme through environment:

struct ThemedButton: View {
  @Environment(\.theme) var theme

  var body: some View {
    Button("Click me") {}
      .background(theme.primary)
  }
}

How should typography tokens handle Dynamic Type?

iOS Dynamic Type allows users to adjust text size for accessibility. Token-based typography should support this feature.

Scaled fonts use UIFontMetrics to adjust sizes:

public struct Typography {
  public static var bodyMd: UIFont {
    let baseFont = UIFont.systemFont(ofSize: 16, weight: .regular)
    return UIFontMetrics(forTextStyle: .body).scaledFont(for: baseFont)
  }
}

Using computed properties instead of static constants ensures fonts scale appropriately.

SwiftUI provides built-in scaling:

Text("Hello")
  .font(.system(size: 16))
  .dynamicTypeSize(.large)

Token definitions can include text style mappings:

{
  "typography": {
    "body": {
      "md": {
        "value": {
          "size": 16,
          "weight": "regular",
          "textStyle": "body"
        }
      }
    }
  }
}

Custom transforms generate scaled font code from these definitions.

How should token pipelines generate iOS outputs?

Style Dictionary configuration for iOS:

{
  platforms: {
    ios: {
      transformGroup: 'ios-swift',
      buildPath: 'ios/Sources/Tokens/',
      files: [{
        destination: 'Tokens.swift',
        format: 'ios-swift/class.swift',
        className: 'Tokens',
        options: {
          accessControl: 'public'
        }
      }]
    },
    iosSwiftUI: {
      transformGroup: 'ios-swiftui',
      buildPath: 'ios/Sources/Tokens/',
      files: [{
        destination: 'TokensSwiftUI.swift',
        format: 'ios-swiftui/class.swift',
        className: 'TokensSwiftUI'
      }]
    }
  }
}

Custom formats may be needed for specific patterns like trait-based colors or scaled typography.

Build integration with Xcode can use build phases:

# Run script build phase
cd "$SRCROOT/../tokens"
npm run build-tokens

Swift Package Manager projects can include token generation in the package build process.

Summary

iOS design tokens enable systematic design value usage through Swift constants that integrate with UIKit and SwiftUI. Token pipelines generate type-safe Swift code from platform-agnostic definitions. Theming requires trait-based approaches or environment-based solutions rather than runtime variable switching. Typography tokens should support Dynamic Type for accessibility. Build automation ensures token generation integrates with iOS development workflows.

Buoy scans your codebase for design system inconsistencies before they ship

Detect Design Drift Free
← Back to Token Management