Swift 6.0 iOS 18+ macOS 15+ visionOS 2+ MIT SPM

DesignFoundation

A production-grade SwiftUI design system. Token-based theming, protocol-driven style swapping, first-class Liquid Glass support, and a full component library — one dependency, instantly consistent across every screen.

DesignFoundation mirrors SwiftUI's own ButtonStyle pattern across every component. Inject a DFTheme once at the app root; every component reads its colors, typography, spacing, and radius from the nearest theme in the environment. Override any subtree. Write custom styles by implementing one function. Zero hardcoded values anywhere.

Installation

Xcode

File → Add Package Dependencies, paste the URL below, and choose Up to Next Major from version 1.1.0.

https://github.com/NerdSnipe-Inc/design-foundation

Package.swift

// Package.swift
dependencies: [
    .package(url: "https://github.com/NerdSnipe-Inc/design-foundation", from: "1.1.0")
],
targets: [
    .target(name: "YourApp", dependencies: ["DesignFoundation"])
]

Quick Start

import DesignFoundation

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .dfTheme(DFTheme(colors: DFColorTokens(primary: .indigo)))
        }
    }
}

// In any view:
DFButton("Get Started") { /* action */ }

DFTextField("Email", text: $email)
    .dfTextFieldStyle(.outlined)

DFCard {
    DFText("Hello", scale: .headline)
}

DFTheme

A single DFTheme struct propagates through SwiftUI's environment. Inject it once at the root and every component responds automatically. Override at any subtree depth.

ContentView()
    .dfTheme(DFTheme(
        colors: DFColorTokens(
            primary: .indigo
        ),
        spacing: DFSpacingTokens(md: 20),
        radius: DFRadiusTokens(md: 12)
    ))
Subtree overrides — wrap any view in .dfTheme(...) to apply a different palette to just that section (e.g. a dark hero banner inside a light screen).

Tokens

Every component reads exclusively from these token namespaces — no hardcoded values anywhere in the library.

Colors — theme.colors

TokenPurpose
.primaryBrand / interactive accent
.surfaceCard and panel backgrounds
.surfaceElevatedRaised overlays, popovers
.textPrimaryBody and heading text
.textSecondaryLabels, placeholders, captions
.textDisabledDisabled control labels
.borderStrokes, dividers
.interactiveFillInput field backgrounds
.destructiveDelete, danger actions
.success / .warning / .infoSemantic status colors

Spacing — theme.spacing

TokenDefault
.xs4 pt
.sm8 pt
.md12 pt
.lg16 pt
.xl24 pt
.xxl32 pt

Radius — theme.radius

TokenDefault
.none0
.sm4 pt
.md8 pt
.lg12 pt
.full9999 pt (pill)

Typography — theme.typography

TokenUsage
.display.fontHero headlines
.title.fontScreen titles
.headline.fontSection headers
.labelLarge.fontProminent inline labels
.body.fontBody text
.bodySmall.fontSecondary body text
.label.fontSmall UI labels
.caption.fontLabels, helper text

Shadows — theme.shadows

TokenFields
.none / .sm / .md / .lgEach a DFShadow: color, radius, x, y

Animation — theme.animation

TokenPurpose
.fastQuick state changes (press, toggle)
.defaultStandard transitions
.slowEmphasis / large layout changes

Per-component overrides — theme.components

Every field is optional — nil inherits the regular tokens above. Confirmed read directly by component styles (e.g. DFButtonStyle reads theme.components.button.cornerRadius ?? theme.radius.md).

Sub-namespaceOverrides
DFButtonTokenscornerRadius, horizontalPadding, verticalPadding, labelStyle
DFTextFieldTokenscornerRadius, horizontalPadding, verticalPadding, inputStyle, labelStyle
DFCardTokenscornerRadius, padding
DFAvatarTokensdefaultSize, borderWidth
DFBadgeTokenscornerRadius, horizontalPadding, verticalPadding
DFIconTokensdefaultSize

Materials — DFMaterialTokens (iOS/macOS 26+)

surfaceMaterial, elevatedMaterial, preferLiquidGlass. Not yet wired into DFTheme.glass styles currently use .regularMaterial/.thickMaterial directly rather than reading this type. Documented here so you know it exists, not because it configures anything yet.

Preset Themes

Four opinionated visual identities ship in the box — each with a distinct color palette, corner radius scale, and shadow weight. One modifier; automatic light/dark switching.

// Recommended — auto-adapts to system light/dark
MyApp()
    .dfThemePreset(.aurora)

// Force a specific variant
PreviewView()
    .dfTheme(.copperDark)
PresetPersonalityRadiusShadowsBest for
.slateProfessional, balancedDefault (md 8)StandardSaaS, developer tools
.auroraVibrant, creativeRounded (md 10)SoftCreative tools, social
.copperWarm, editorialSharp (md 6)DefinedFinance, content readers
.sageCalm, organicVery rounded (md 12)AiryHealth, wellness

Theme Presets Guide

Full color palettes, radius and shadow specs, API reference, and power-user patterns.

Browse Themes →

Style System

Every component exposes a style protocol with a single makeBody(configuration:) method — the same pattern as SwiftUI's ButtonStyle. Styles propagate through the environment, compose with each other, and apply hierarchically.

// Apply a style to an entire section
VStack { ... }
    .dfButtonStyle(.outlined)
    .dfCardStyle(.glass)

// Override for a single component
DFButton("Delete", role: .destructive) { }
    .dfButtonStyle(.ghost)

// Liquid Glass across your whole UI (iOS/macOS 26+)
ContentView()
    .dfButtonStyle(.glass)
    .dfCardStyle(.glass)
    .dfTooltipStyle(.glass)

Writing a custom style means implementing one function. All protocols are open; built-in styles are concrete structs you can copy and fork.

struct MyButtonStyle: DFButtonStyle {
    func makeBody(configuration: DFButtonStyleConfiguration) -> some View {
        configuration.label
            .padding(.horizontal, configuration.theme.spacing.lg)
            .background(configuration.theme.colors.primary)
            .clipShape(Capsule())
            .opacity(configuration.isPressed ? 0.7 : 1)
    }
}

Primitives

ComponentBuilt-in Styles
DFButton.filled .outlined .ghost .tinted .glass¹
DFTextscale: display, title, headline, labelLarge, body, bodySmall, label, caption
DFIconSF Symbol wrapper with token-driven size and color
DFBadge.default .subtle .outlined .glass¹
DFAvatar.circle .rounded .ring .glass¹ — image or initials, presence indicators
DFDivider.standard .thick .subtle — horizontal/vertical, labeled variant

Inputs

All input components share DFValidationState (.none / .valid / .error(String)) for consistent error display.

ComponentBuilt-in Styles / Notes
DFTextField.outlined .filled
DFSecureField.outlined .filled — reveal toggle built in
DFValidatedTextFieldReads/writes a named field on a DFFormState you register validators on separately — DFRequiredValidator, DFEmailValidator, DFMinLengthValidator, DFMaxLengthValidator, DFRegexValidator, or your own DFFieldValidator.
DFToggle.switch .checkbox .glass¹
DFSlider.standard .labeled .glass¹
DFPicker.segmented .menu .wheel .glass¹
DFDatePicker.compact .graphical .wheel .glass¹
DFCheckbox.default
// DFFormState — observable state for a set of validated fields
let formState = DFFormState(fields: [
    "email":    [DFRequiredValidator(), DFEmailValidator()],
    "password": [DFRequiredValidator(), DFMinLengthValidator(minLength: 8)],
])

DFValidatedTextField("Email", field: "email", form: formState)
DFSecureField(
    "Password",
    text: formState.binding(for: "password"),
    validationState: formState.validationState(for: "password")
)

DFButton("Sign in") {
    guard formState.validate() else { return }
    submit(formState.values["email", default: ""], formState.values["password", default: ""])
}

Layout

ComponentBuilt-in Styles
DFCard.elevated .outlined .filled .glass¹

Overlays

These are applied as view modifiers (.dfModal(), .dfSheet(), .dfPopover(), .dfTooltip()) — not constructed directly like the components above.

ComponentBuilt-in Styles
DFModal.standard, DFGlassModalStyle()¹² — no .glass shorthand for Modal specifically
DFSheet.standard .compact .glass¹
DFPopover.arrow .compact .glass¹
DFTooltip.bubble .glass¹

² DFGlassModalStyle exists but has no .glass convenience accessor like the other overlay styles — construct it directly: .dfModalStyle(DFGlassModalStyle()).

Supplementary

ComponentNotes
DFAlertConfiguration + .dfAlert()Convenience wrapper over native SwiftUI alert
DFToastQueue + .dfToast()Queue management and auto-dismiss
DFSkeletonShimmer animation placeholder
DFProgressBarLinear, circular, and indeterminate variants
DFListRowLeading/trailing slots and disclosure indicator
DFListSwipe-delete, reorder, and multi-select
DFTableSortable columns
DFDataTableSelection, multi-sort, empty slot — cross-platform
DFDataGridInline edit, bulk actions, column config, large-dataset paging

¹ .glass styles require iOS 26+ / macOS 26+.


Add-on Packages

DesignFoundation is the free, open-source foundation. One commercial package — DesignFoundationPro — builds on top, adding drop-in blocks for common UI patterns and full screens for complete vertical feature sets. Both share the same DFTheme as the free package, so a brand color change ripples through everything identically.

DesignFoundationPro

29 drop-in blocks, 47 production screens across 9 verticals, 18 shell layouts, and 9 wired composition examples. All components adapt to iOS, macOS, and visionOS automatically — no platform guards required.

Browse Pro →
🖥

DFPlayground — See it before you build it

Free macOS companion app with every component, block, screen, and theme interactive and live. Browse the full catalog, switch themes, open any Pro screen — then decide what to use.

⬇ Download free · 9.9 MB

Installation

Add DesignFoundation via SPM (free). Pro is a licensed add-on — private repo access provided after purchase:

// Package.swift — Foundation (public)
dependencies: [
    .package(url: "https://github.com/NerdSnipe-Inc/design-foundation", from: "1.1.0"),
    // Pro: private SPM URL included with your license
]

Integration guide → · Use cases → · Get Pro access →


Platforms

PlatformMinimum Version
iOS18.0
macOS15.0
visionOS2.0

.glass styles require iOS 26+ / macOS 26+. All other styles work on the minimum versions above.

How "no platform guards" actually works: DFPlatformContext — a resolved-once struct (idiom, horizontalSizeClass, isLiquidGlassAvailable) — is injected into the SwiftUI environment alongside DFTheme by .dfTheme()/.dfThemePreset(). Component styles read this context internally to pick their rendering path, instead of your app branching on platform with #if os().

License

MIT © 2026 NerdSnipe Inc. DesignFoundation is free and open-source. View LICENSE →

Try DFPlayground free