Composability over inheritance.
A SwiftUI design system where behaviors are primitives, every magic number has a name, and one import covers five Apple platforms.
Everything you need
Tokens, primitives, and components — one import, all platforms.
Three-Tier Tokens
Primitives, semantic, component. Adaptive light/dark colors, 4pt spacing grid, SF Rounded typography, motion presets.
Behavior Primitives
.lubaPressable(), .lubaSwipeable(), .lubaExpandable(), .lubaLongPressable(), .lubaShimmerable() — composable interactions.
25 Components
Buttons, cards, text fields, toggles, sliders, tabs, toasts, sheets, menus, tooltips — production-ready.
Accessibility
VoiceOver, Dynamic Type, 44pt touch targets, WCAG AA contrast, reduced motion — via LubaConfig.
AI-Native Architecture
Semantic naming, strict tokenization, documented rationale. Every magic number has a name.
Five Platforms
iOS, macOS, watchOS, tvOS, visionOS from a single package with platform-adaptive behavior.
Design decisions
The math and reasoning behind every token. No arbitrary values.
4pt base grid
xs(4) → sm(8) → md(12) → lg(16) → xl(24) → xxl(32) → xxxl(48) → huge(64). After the initial 2x jump, the scale alternates x1.5 and x1.33 — landing on clean 4pt-grid values with perceptible gaps between every step.
Size-relative feedback
Smaller elements shrink more: compact 0.95 (5%), standard 0.97 (3%), prominent 0.98 (2%). A 44pt icon button needs exaggerated motion to feel responsive; a full-width card needs subtlety or it looks broken.
Two systems, one intent
LubaMotion holds raw constants (scale values, durations). LubaAnimations holds applied Animation objects and transitions. Press spring: 0.25s response, 0.65 damping — quick with slight bounce. State changes: 0.35s, 0.75 damping — deliberate.
Sage green, WCAG AA
Accent is #6B8068 (light) / #9AB897 (dark) — both meet 4.5:1 contrast against their backgrounds. Surface hierarchy: background → surface → surfaceSecondary → surfaceTertiary. Card shadows strengthen 1.5x in dark mode.
SF Rounded, 13 sizes
System font for native feel. Rounded weight for warmth. Button-specific sizes: small 13pt, medium 15pt, large 17pt — mapped to Apple HIG recommended touch targets.
Three tiers, strict boundaries
Tier 1 (LubaPrimitives): raw hex and numbers — never used in components. Tier 2 (LubaColors, LubaSpacing): semantic, adaptive — what components consume. Tier 3 (LubaButtonTokens, etc.): per-component overrides.
Low-friction API
Just works out of the box. Customize when you want, not because you have to.
import LubaUI
struct ContentView: View {
@State private var name = ""
var body: some View {
VStack(spacing: LubaSpacing.lg) {
LubaCard(elevation: .low) {
LubaTextField("Name", text: $name)
LubaToggle(isOn: $notify, label: "Notifications")
}
LubaButton("Save", style: .primary) { save() }
LubaButton("Cancel", style: .ghost) { dismiss() }
}
.lubaPressable { navigate() } // Any view, tappable
}
}Behavior primitives
Interactions extracted into composable modifiers. Try them.
.lubaPressable()scale(0.97), spring(0.25s, 0.65 damping)
.lubaExpandable()spring(0.35s, 0.75 damping)
.lubaSwipeable()presets: .delete, .archive, .pin
.lubaShimmerable()1.5s cycle, applied to any view
.lubaLongPressable()progress ring, confirms destructive actions
25 components
Four categories. All use semantic tokens. All composable with primitives.
Controls
LubaButtonLubaTextFieldLubaTextAreaLubaSearchBarLubaCheckboxLubaRadioLubaToggleLubaSliderLubaStepperLubaRatingContainers
LubaCardLubaSheetLubaTabsLubaMenuLubaDividerFeedback
LubaAlertLubaToastLubaProgressLubaSkeletonLubaSpinnerData Display
LubaBadgeLubaAvatarLubaChipLubaIconLubaLinkLubaTooltipGet started
Open source, MIT licensed. Add it with Swift Package Manager.
.package(url: "https://github.com/ermanakar/LubaUI.git", from: "1.0.0")