Build a Reusable SwiftUI Component Library

SwiftUI makes it easy to build UI — but building reusable components that look consistent across your entire app is a different challenge.

As apps grow, UI duplication becomes a real problem:

repeated button styles

inconsistent card shapes

duplica…


This content originally appeared on DEV Community and was authored by Sebastien Lato

SwiftUI makes it easy to build UI — but building reusable components that look consistent across your entire app is a different challenge.

As apps grow, UI duplication becomes a real problem:

  • repeated button styles
  • inconsistent card shapes
  • duplicated text modifiers
  • copy-paste shadows
  • multiple versions of the same layout

A component library solves all of this.

Today you’ll learn how to build a modern, scalable, Apple-style SwiftUI Component Library that includes:

  • buttons
  • cards
  • text fields
  • floating panels
  • chips
  • design tokens (colors, radii, shadows)
  • reusable modifiers
  • consistent styling

This is the exact structure I use in real production apps.

Let’s build it. 🚀

🧱 1. Start With a Design Folder

Design/
├── Colors.swift
├── Radii.swift
├── Shadows.swift
└── Typography.swift

This gives your app consistent design tokens.

Colors.swift

enum AppColor {
    static let primary = Color.blue
    static let background = Color(.systemBackground)
    static let glassStroke = Color.white.opacity(0.25)
}

Radii.swift

enum AppRadius {
    static let small: CGFloat = 10
    static let medium: CGFloat = 16
    static let large: CGFloat = 22
}

Shadows.swift

enum AppShadow {
    static let card = Color.black.opacity(0.18)
    static let glow = Color.blue.opacity(0.3)
}

Typography.swift

enum AppFont {
    static let title = Font.system(.title3, design: .rounded).bold()
    static let body = Font.system(.body, design: .rounded)
}

One place → full app consistency.

🔵 2. Reusable Button Styles

A clean button style gives your UI an identity.

PrimaryButton

struct PrimaryButton: View {
    let title: String
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            Text(title)
                .font(AppFont.body.bold())
                .padding(.horizontal, 28)
                .padding(.vertical, 14)
                .background(AppColor.primary)
                .foregroundColor(.white)
                .clipShape(RoundedRectangle(cornerRadius: AppRadius.medium, style: .continuous))
                .shadow(color: AppShadow.card, radius: 16, y: 8)
        }
    }
}

Usage:

PrimaryButton(title: "Continue") {
    print("Pressed")
}

🟦 3. Glass Card Component (Reusable)

struct GlassCard<Content: View>: View {
    @ViewBuilder let content: () -> Content

    var body: some View {
        content()
            .padding(20)
            .background(.ultraThinMaterial)
            .clipShape(RoundedRectangle(cornerRadius: AppRadius.large, style: .continuous))
            .overlay(
                RoundedRectangle(cornerRadius: AppRadius.large, style: .continuous)
                    .stroke(AppColor.glassStroke, lineWidth: 1)
            )
            .shadow(color: AppShadow.card, radius: 24, y: 12)
    }
}

Usage:

GlassCard {
    VStack(alignment: .leading) {
        Text("Glass Card")
            .font(AppFont.title)
        Text("Reusable glassmorphic component.")
            .foregroundColor(.secondary)
    }
}

🟩 4. TextField Component (Modern, Clean)

struct AppTextField: View {
    var title: String
    @Binding var text: String

    var body: some View {
        TextField(title, text: $text)
            .padding(.horizontal, 14)
            .padding(.vertical, 12)
            .background(.ultraThinMaterial)
            .clipShape(RoundedRectangle(cornerRadius: AppRadius.medium))
            .overlay(
                RoundedRectangle(cornerRadius: AppRadius.medium)
                    .stroke(AppColor.glassStroke)
            )
            .shadow(color: AppShadow.card.opacity(0.25), radius: 12, y: 6)
    }
}

Usage:

@State private var name = ""

AppTextField(title: "Name", text: $name)

🔶 5. Chips / Tags

struct Chip: View {
    let label: String
    let icon: String?

    var body: some View {
        HStack(spacing: 6) {
            if let icon { Image(systemName: icon) }
            Text(label)
        }
        .font(.caption)
        .padding(.horizontal, 12)
        .padding(.vertical, 8)
        .background(.ultraThinMaterial)
        .clipShape(Capsule())
        .overlay(Capsule().stroke(AppColor.glassStroke))
    }
}

Example:

HStack {
    Chip(label: "SwiftUI", icon: "swift")
    Chip(label: "Design", icon: "paintbrush")
}

🪟 6. Floating Panel (Reusable Bottom Sheet Top Section)

struct FloatingPanel<Content: View>: View {
    @ViewBuilder let content: () -> Content

    var body: some View {
        VStack(spacing: 0) {
            Capsule()
                .fill(AppColor.glassStroke)
                .frame(width: 40, height: 6)
                .padding(.top, 10)

            content()
                .padding()
        }
        .background(.regularMaterial)
        .clipShape(RoundedRectangle(cornerRadius: AppRadius.large, style: .continuous))
        .shadow(color: .black.opacity(0.25), radius: 30, y: 14)
    }
}

🧩 7. Reusable Modifiers (Powerful Tool!)

A clean reusable modifier:

struct CardPadding: ViewModifier {
    func body(content: Content) -> some View {
        content
            .padding(20)
            .clipShape(RoundedRectangle(cornerRadius: AppRadius.large))
    }
}

extension View {
    func cardPadding() -> some View {
        modifier(CardPadding())
    }
}

Modifiers keep your views clean and declarative.

🗂 8. Suggested Folder Structure

Design/
│  Colors.swift
│  Radii.swift
│  Shadows.swift
│  Typography.swift
│
Components/
│  Buttons/
│  Cards/
│  TextFields/
│  Panels/
│  Chips/
│  Modifiers/

Everything clean. Everything scalable.

🚀 Final Thoughts

A SwiftUI Component Library gives you:

  • consistent design
  • faster iteration
  • reusable building blocks
  • scalable architecture
  • easier team onboarding
  • more polished UI

This is how you go from “building screens” → to building systems.


This content originally appeared on DEV Community and was authored by Sebastien Lato


Print Share Comment Cite Upload Translate Updates
APA

Sebastien Lato | Sciencx (2025-12-02T00:37:11+00:00) Build a Reusable SwiftUI Component Library. Retrieved from https://www.scien.cx/2025/12/02/build-a-reusable-swiftui-component-library/

MLA
" » Build a Reusable SwiftUI Component Library." Sebastien Lato | Sciencx - Tuesday December 2, 2025, https://www.scien.cx/2025/12/02/build-a-reusable-swiftui-component-library/
HARVARD
Sebastien Lato | Sciencx Tuesday December 2, 2025 » Build a Reusable SwiftUI Component Library., viewed ,<https://www.scien.cx/2025/12/02/build-a-reusable-swiftui-component-library/>
VANCOUVER
Sebastien Lato | Sciencx - » Build a Reusable SwiftUI Component Library. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/12/02/build-a-reusable-swiftui-component-library/
CHICAGO
" » Build a Reusable SwiftUI Component Library." Sebastien Lato | Sciencx - Accessed . https://www.scien.cx/2025/12/02/build-a-reusable-swiftui-component-library/
IEEE
" » Build a Reusable SwiftUI Component Library." Sebastien Lato | Sciencx [Online]. Available: https://www.scien.cx/2025/12/02/build-a-reusable-swiftui-component-library/. [Accessed: ]
rf:citation
» Build a Reusable SwiftUI Component Library | Sebastien Lato | Sciencx | https://www.scien.cx/2025/12/02/build-a-reusable-swiftui-component-library/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.