Open Source · Design System · Swift 5.9+

Composability over inheritance.

A SwiftUI design system where behaviors are primitives, every magic number has a name, and one import covers five Apple platforms.

View on GitHubSwift 5.9+ · SwiftUI · Swift Package Manager · MIT License
iOS 16+macOS 13+watchOS 9+tvOS 16+visionOS 1+

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.

Showcase app

Every component, primitive, and pattern — running on device.

LubaUI Composability showcase
ComposabilityMix & match primitives on any view
LubaUI Form Patterns showcase
Form PatternsSignup, settings, and payment flows
LubaUI Theming showcase
ThemingFour themes with live preview
LubaUI Typography showcase
TypographySF Rounded type scale in context
LubaUI Loading States showcase
Loading StatesSkeletons, spinners, and progress

Design decisions

The math and reasoning behind every token. No arbitrary values.

Spacing

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.

Press scale

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.

Motion

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.

Color

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.

Typography

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.

Tokens

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.

ContentView.swift
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()
Swipe this row left

presets: .delete, .archive, .pin

.lubaShimmerable()

1.5s cycle, applied to any view

.lubaLongPressable()

progress ring, confirms destructive actions

AI-Native

Built for AI agents

The first SwiftUI design system with an MCP server. AI agents can query tokens, validate spacing, and generate correct code — without reading every source file.

MCP Server

7 tools for token lookup, component reference, spacing validation, color palettes, and code suggestions. Works with Claude Code, Cursor, and any MCP-compatible agent.

Terminal
claude mcp add lubaui -- npx lubaui-mcp

llms.txt

A 570-line AI agent reference covering the full architecture, every token, all 25 component APIs, and 6 usage patterns. One file, zero ambiguity.

Reference
shopofluba.de/lubaui/llms.txt
lookup_tokenlookup_componentlookup_primitivevalidate_spacingvalidate_radiusget_color_palettesuggest_tokens

25 components

Four categories. All use semantic tokens. All composable with primitives.

Controls

LubaButtonLubaTextFieldLubaTextAreaLubaSearchBarLubaCheckboxLubaRadioLubaToggleLubaSliderLubaStepperLubaRating

Containers

LubaCardLubaSheetLubaTabsLubaMenuLubaDivider

Feedback

LubaAlertLubaToastLubaProgressLubaSkeletonLubaSpinner

Data Display

LubaBadgeLubaAvatarLubaChipLubaIconLubaLinkLubaTooltip

Get started

Open source, MIT licensed. Add it with Swift Package Manager.

Package.swift
.package(url: "https://github.com/ermanakar/LubaUI.git", from: "1.0.0")
View on GitHub