Library

iOS · SwiftUI

Bring Sitka's color, spacing, radius, shadow, and typography tokens into a SwiftUI project as typed Swift constants — generated from the same source JSON that powers the web.

1

Download the Swift token file

Go to the Token Export page and download SitkaTokens.swift. It is auto-generated from tokens.json — regenerate whenever tokens change.

Or generate it yourself using Style Dictionary:

bash
npx style-dictionary build --config style-dictionary.config.js
# outputs dist/SitkaTokens.swift
2

Add to your Xcode project

  1. Drag SitkaTokens.swift into your Xcode project navigator.
  2. In the Add Files dialog, ensure Copy items if needed is checked.
  3. Make sure the file is added to your app target.
3

What's in SitkaTokens.swift

SitkaTokens.swift
swift
import SwiftUI

public enum SitkaTokens {

  // MARK: — Color
  public enum Color {
    // Brand
    public static let brandCyan    = SwiftUI.Color(hex: "#00C0E8")
    public static let brand500     = SwiftUI.Color(hex: "#34a865")
    public static let brand600     = SwiftUI.Color(hex: "#289452")

    // Semantic
    public static let success      = SwiftUI.Color(hex: "#22c55e")
    public static let warning      = SwiftUI.Color(hex: "#f59e0b")
    public static let error        = SwiftUI.Color(hex: "#ef4444")
    public static let info         = SwiftUI.Color(hex: "#3b82f6")

    // Dark-mode surface
    public static let background   = SwiftUI.Color(hex: "#09090c")
    public static let surface      = SwiftUI.Color(hex: "#0d0d11")
    public static let surfaceRaised = SwiftUI.Color(hex: "#16161c")
    public static let accent       = brandCyan
    public static let textPrimary  = SwiftUI.Color(hex: "#f2f2f6")
    public static let textSecondary = SwiftUI.Color(hex: "#9b9baa")
  }

  // MARK: — Spacing
  public enum Spacing {
    public static let s1: CGFloat = 4
    public static let s2: CGFloat = 8
    public static let s3: CGFloat = 12
    public static let s4: CGFloat = 16
    public static let s5: CGFloat = 20
    public static let s6: CGFloat = 24
    public static let s8: CGFloat = 32
    public static let s10: CGFloat = 40
    public static let s12: CGFloat = 48
    public static let s16: CGFloat = 64
  }

  // MARK: — Border Radius
  public enum Radius {
    public static let sm: CGFloat = 6
    public static let md: CGFloat = 10
    public static let lg: CGFloat = 14
    public static let xl: CGFloat = 20
    public static let full: CGFloat = 9999
  }

  // MARK: — Typography
  public enum Typography {
    public static let fontSans = "Inter"
    public static let sizeXS: CGFloat = 11
    public static let sizeSM: CGFloat = 13
    public static let sizeBase: CGFloat = 15
    public static let sizeLG: CGFloat = 17
    public static let sizeXL: CGFloat = 20
    public static let size2XL: CGFloat = 24
  }
}

// MARK: — Color hex helper
private extension SwiftUI.Color {
  init(hex: String) {
    let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
    var int: UInt64 = 0
    Scanner(string: hex).scanHexInt64(&int)
    let r = Double((int >> 16) & 0xff) / 255
    let g = Double((int >>  8) & 0xff) / 255
    let b = Double( int        & 0xff) / 255
    self.init(red: r, green: g, blue: b)
  }
}

Usage examples

Colors

swift
Text("Hello Sitka")
    .foregroundStyle(SitkaTokens.Color.textPrimary)

Rectangle()
    .fill(SitkaTokens.Color.accent)
    .frame(height: 2)

Spacing & radius

swift
VStack(spacing: SitkaTokens.Spacing.s4) {
    Text("Card title")
    Text("Subtitle")
        .foregroundStyle(SitkaTokens.Color.textSecondary)
}
.padding(SitkaTokens.Spacing.s6)
.background(SitkaTokens.Color.surface)
.clipShape(RoundedRectangle(cornerRadius: SitkaTokens.Radius.lg))

Primary button

swift
struct SitkaButton: View {
    let title: String
    var action: () -> Void

    var body: some View {
        Button(action: action) {
            Text(title)
                .font(.system(size: SitkaTokens.Typography.sizeSM, weight: .medium))
                .foregroundStyle(.white)
                .padding(.horizontal, SitkaTokens.Spacing.s5)
                .frame(height: 40)
                .background(SitkaTokens.Color.accent)
                .clipShape(RoundedRectangle(cornerRadius: SitkaTokens.Radius.md))
        }
        .buttonStyle(.plain)
    }
}

// Usage
SitkaButton(title: "Get Started") {
    print("tapped")
}

Dark / Light mode

Sitka is dark-first. To support both modes, define adaptive colors using UIColor or Color Assets in Xcode and reference the same semantic names:

swift
// In Assets.xcassets / SitkaColors.xcassets
// Create a Color Set named "background" with:
//   Light: #FAFAFA
//   Dark:  #09090C
// Then use it as:
Color("background")

ThemeManager

For apps that let users switch between Sitka defaults and custom accent colors, Sitka provides a ThemeManager observable object. It drives the effectiveAccent pattern, root .tint() wiring, and view-tree rebuilds via .id(themeManager.useSitkaDefaults).

Important: Text and surface tokens must use adaptive system colors (Color(.label), Color(.systemBackground)), not fixed hex values, to follow the system light/dark mode correctly.

See the full implementation guide: Wire Sitka's ThemeManager in SwiftUI →

Requirements

Swift

5.9+

iOS

16+

Xcode

15+

Back to all libraries.