Help us improve
Share bugs, ideas, or general feedback.
From design-to-code
Converts Figma, Sketch, or Penpot design specifications to SwiftUI view code with layouts like VStack/HStack, modifiers, and theme token integration.
npx claudepluginhub arustydev/agents --plugin design-to-codeHow this skill is triggered — by the user, by Claude, or both
Slash command
/design-to-code:design-to-swiftuiThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Convert design component specifications to SwiftUI view code.
Translates between Figma designs and SwiftUI code in both directions: design-to-code and code-to-design. Routes to direction-specific reference docs.
Converts Stitch mobile designs to native iOS SwiftUI views with VStack/HStack/ZStack layout mapping, dark mode color assets, NavigationStack/TabView routing, and Xcode project structure.
Provides best practices and examples for SwiftUI views, components, navigation hierarchies, custom modifiers, responsive layouts with stacks/grids, and state management (@State/@Binding). Use for creating/refactoring iOS UI.
Share bugs, ideas, or general feedback.
Convert design component specifications to SwiftUI view code.
This skill transforms design specifications (from Figma, Sketch, or Penpot) into idiomatic SwiftUI views with proper modifiers, layout containers, and theme token integration.
This skill covers:
This skill does NOT cover:
design-tokens-extraction skill)| Design Element | SwiftUI Component |
|---|---|
| Horizontal layout | HStack |
| Vertical layout | VStack |
| Overlapping layers | ZStack |
| Auto-layout | Stack with spacing |
| Grid | LazyVGrid / LazyHGrid |
| Scroll container | ScrollView |
| Text | Text with modifiers |
| Rectangle | RoundedRectangle or Rectangle |
| Circle | Circle |
| Image | Image / AsyncImage |
| Button | Button with custom label |
| Design Property | SwiftUI Modifier |
|---|---|
| Fill color | .fill() / .foregroundStyle() |
| Stroke | .stroke() / .overlay() |
| Corner radius | .clipShape(RoundedRectangle()) |
| Shadow | .shadow() |
| Opacity | .opacity() |
| Padding | .padding() |
| Size | .frame() |
| Position | .offset() / .position() |
Read the design component from MCP and identify:
Auto-layout (horizontal):
HStack(alignment: .<alignment>, spacing: <gap>) {
// children
}
Auto-layout (vertical):
VStack(alignment: .<alignment>, spacing: <gap>) {
// children
}
Grid layout:
let columns = [
GridItem(.flexible()),
GridItem(.flexible())
]
LazyVGrid(columns: columns, spacing: <gap>) {
// children
}
Absolute positioning (rare in SwiftUI):
ZStack {
// position children with .offset() or .position()
}
For each design element, generate SwiftUI code:
Text elements:
Text("<content>")
.font(<Theme.Typography.style>)
.foregroundStyle(<Theme.Colors.color>)
.lineLimit(<lines>)
.multilineTextAlignment(.<alignment>)
Shapes with fill:
RoundedRectangle(cornerRadius: Theme.Radius.<size>)
.fill(Theme.Colors.<color>)
.frame(width: <width>, height: <height>)
.shadow(color: .black.opacity(0.1), radius: 4, y: 2)
Images:
// Local image
Image("<assetName>")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: <width>, height: <height>)
.clipShape(RoundedRectangle(cornerRadius: Theme.Radius.<size>))
// Remote image
AsyncImage(url: URL(string: "<url>")) { image in
image
.resizable()
.aspectRatio(contentMode: .fill)
} placeholder: {
ProgressView()
}
.frame(width: <width>, height: <height>)
Buttons:
Button {
// action
} label: {
HStack(spacing: 8) {
Image(systemName: "<icon>")
Text("<label>")
}
.font(Theme.Typography.<style>)
.foregroundStyle(Theme.Colors.<textColor>)
.padding(.horizontal, Theme.Spacing.<h>)
.padding(.vertical, Theme.Spacing.<v>)
.background(Theme.Colors.<bgColor>)
.clipShape(RoundedRectangle(cornerRadius: Theme.Radius.<size>))
}
Wrap the generated code in a reusable SwiftUI View:
import SwiftUI
struct <ComponentName>View: View {
// Properties extracted from design variants
let title: String
let subtitle: String?
var onTap: (() -> Void)?
var body: some View {
VStack(alignment: .leading, spacing: Theme.Spacing.sm) {
Text(title)
.font(Theme.Typography.headlineMedium)
.foregroundStyle(Theme.Colors.text)
if let subtitle {
Text(subtitle)
.font(Theme.Typography.bodyMedium)
.foregroundStyle(Theme.Colors.textSecondary)
}
}
.padding(Theme.Spacing.md)
.background(Theme.Colors.surface)
.clipShape(RoundedRectangle(cornerRadius: Theme.Radius.md))
.onTapGesture {
onTap?()
}
}
}
#Preview {
<ComponentName>View(
title: "Preview Title",
subtitle: "Preview subtitle text"
)
.padding()
}
Design spec:
struct CardView<Content: View>: View {
let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
content
}
.background(Theme.Colors.surface)
.clipShape(RoundedRectangle(cornerRadius: Theme.Radius.lg))
.shadow(
color: .black.opacity(0.08),
radius: 8,
y: 4
)
}
}
Design spec defines Primary, Secondary, Ghost variants:
enum ButtonVariant {
case primary, secondary, ghost
var backgroundColor: Color {
switch self {
case .primary: Theme.Colors.primary
case .secondary: Theme.Colors.surface
case .ghost: .clear
}
}
var foregroundColor: Color {
switch self {
case .primary: Theme.Colors.onPrimary
case .secondary: Theme.Colors.primary
case .ghost: Theme.Colors.primary
}
}
}
struct ThemedButton: View {
let title: String
let variant: ButtonVariant
let action: () -> Void
var body: some View {
Button(action: action) {
Text(title)
.font(Theme.Typography.labelLarge)
.foregroundStyle(variant.foregroundColor)
.padding(.horizontal, Theme.Spacing.lg)
.padding(.vertical, Theme.Spacing.md)
.background(variant.backgroundColor)
.clipShape(RoundedRectangle(cornerRadius: Theme.Radius.md))
}
}
}
Design spec with leading icon, title/subtitle, trailing accessory:
struct ListItemView: View {
let icon: String
let title: String
let subtitle: String?
let accessory: Accessory
enum Accessory {
case chevron
case toggle(Binding<Bool>)
case badge(String)
case none
}
var body: some View {
HStack(spacing: Theme.Spacing.md) {
Image(systemName: icon)
.font(.system(size: 20))
.foregroundStyle(Theme.Colors.primary)
.frame(width: 24)
VStack(alignment: .leading, spacing: 2) {
Text(title)
.font(Theme.Typography.bodyLarge)
.foregroundStyle(Theme.Colors.text)
if let subtitle {
Text(subtitle)
.font(Theme.Typography.bodySmall)
.foregroundStyle(Theme.Colors.textSecondary)
}
}
Spacer()
accessoryView
}
.padding(.vertical, Theme.Spacing.sm)
.padding(.horizontal, Theme.Spacing.md)
}
@ViewBuilder
private var accessoryView: some View {
switch accessory {
case .chevron:
Image(systemName: "chevron.right")
.foregroundStyle(Theme.Colors.textSecondary)
case .toggle(let isOn):
Toggle("", isOn: isOn)
.labelsHidden()
case .badge(let text):
Text(text)
.font(Theme.Typography.labelSmall)
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(Theme.Colors.primary)
.foregroundStyle(Theme.Colors.onPrimary)
.clipShape(Capsule())
case .none:
EmptyView()
}
}
}
Reference design tokens through the Theme struct:
// Colors
Theme.Colors.primary
Theme.Colors.surface
Theme.Colors.text
Theme.Colors.textSecondary
// Typography
Theme.Typography.displayLarge
Theme.Typography.headlineMedium
Theme.Typography.bodyLarge
Theme.Typography.labelSmall
// Spacing
Theme.Spacing.xs // 4
Theme.Spacing.sm // 8
Theme.Spacing.md // 16
Theme.Spacing.lg // 24
Theme.Spacing.xl // 32
// Corner Radius
Theme.Radius.sm // 4
Theme.Radius.md // 8
Theme.Radius.lg // 16
Theme.Radius.full // 9999
| Design Name | SwiftUI Name |
|---|---|
Button/Primary | PrimaryButton |
Card - Article | ArticleCardView |
List Item/Default | ListItemView |
Header/Large | LargeHeaderView |
Input/Text Field | TextFieldView |
design-tokens-extraction skill - Extract tokens firstdesign-token-swift style - Swift code output formatswiftui-components skill - SwiftUI component patterns