From pencil-design-tools
Converts Pencil.dev (.pen) designs to SwiftUI code. Reads .pen file structure and generates native SwiftUI Views with proper layout, styling, and component hierarchy. Use when you have a .pen mockup and need SwiftUI implementation.
How this skill is triggered — by the user, by Claude, or both
Slash command
/pencil-design-tools:pen-to-swiftuiThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Converts .pen design files to native SwiftUI code with accurate layout and styling.
Converts .pen design files to native SwiftUI code with accurate layout and styling.
Activate when user:
| .pen | SwiftUI |
|---|---|
frame + layout: "vertical" | VStack(spacing: gap) |
frame + layout: "horizontal" | HStack(spacing: gap) |
frame + layout: "none" | ZStack |
group | Group |
| .pen | SwiftUI |
|---|---|
fill_container | .frame(maxWidth: .infinity) or maxHeight: .infinity |
fit_content | (default SwiftUI behavior) |
width: 100 | .frame(width: 100) |
height: 200 | .frame(height: 200) |
| .pen | SwiftUI |
|---|---|
justifyContent: "start" | alignment: .leading (HStack) / .top (VStack) |
justifyContent: "center" | alignment: .center |
justifyContent: "end" | alignment: .trailing (HStack) / .bottom (VStack) |
justifyContent: "space_between" | Spacer() between items |
alignItems: "start" | Cross-axis alignment |
alignItems: "center" | Cross-axis center |
| .pen | SwiftUI |
|---|---|
text | Text("content") |
rectangle | Rectangle() or RoundedRectangle(cornerRadius:) |
ellipse | Circle() or Ellipse() |
line | Divider() or custom Path |
path | Path { } with geometry |
| .pen | SwiftUI |
|---|---|
icon_font (lucide/feather) | Image(systemName: "sf.symbol.name") |
| Custom mapping needed | See SF Symbols mapping table below |
| .pen | SwiftUI |
|---|---|
fill: "#RRGGBB" | .background(Color(hex: "RRGGBB")) |
fill: "$variable" | .background(Color.theme.variableName) |
stroke | .overlay(RoundedRectangle().stroke()) |
cornerRadius: 8 | .clipShape(RoundedRectangle(cornerRadius: 8)) |
padding: 16 | .padding(16) |
padding: [8, 16] | .padding(.vertical, 8).padding(.horizontal, 16) |
opacity: 0.5 | .opacity(0.5) |
effect: shadow | .shadow(color:radius:x:y:) |
| .pen | SwiftUI |
|---|---|
fontSize: 24 | .font(.system(size: 24)) |
fontWeight: "bold" | .fontWeight(.bold) |
fontFamily | .font(.custom("FontName", size:)) |
textAlign: "center" | .multilineTextAlignment(.center) |
fill on text | .foregroundColor(Color(...)) |
| .pen | SwiftUI |
|---|---|
ref to reusable component | Custom View struct |
descendants overrides | View parameters/bindings |
mcp__pencil__get_editor_state() - Get current .pen file
mcp__pencil__batch_get({nodeIds: ["targetFrameId"], readDepth: 10}) - Full structure
mcp__pencil__get_variables() - Get design tokens/colors
reusable: true)// Theme.swift
import SwiftUI
extension Color {
static let theme = ColorTheme()
}
struct ColorTheme {
let primary = Color(hex: "007AFF")
let background = Color(hex: "F5F5F5")
let textPrimary = Color(hex: "000000")
// ... from .pen variables
}
// ButtonPrimary.swift (from reusable component)
struct ButtonPrimary: View {
let title: String
let action: () -> Void
var body: some View {
Button(action: action) {
Text(title)
.font(.system(size: 16, weight: .semibold))
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.padding(.vertical, 16)
.background(Color.theme.primary)
.clipShape(RoundedRectangle(cornerRadius: 12))
}
}
}
// LoginView.swift (from frame)
struct LoginView: View {
@State private var email = ""
@State private var password = ""
var body: some View {
VStack(spacing: 24) {
// Header
Text("Welcome Back")
.font(.system(size: 28, weight: .bold))
.foregroundColor(.theme.textPrimary)
// Form fields
VStack(spacing: 16) {
TextField("Email", text: $email)
.textFieldStyle(.roundedBorder)
SecureField("Password", text: $password)
.textFieldStyle(.roundedBorder)
}
// Button
ButtonPrimary(title: "Sign In") {
// Action
}
Spacer()
}
.padding(24)
.background(Color.theme.background)
}
}
mcp__pencil__get_screenshot(nodeId) - Compare design to implementation
Common Lucide/Feather → SF Symbols:
| Lucide/Feather | SF Symbol |
|---|---|
arrow-left | chevron.left |
arrow-right | chevron.right |
check | checkmark |
x | xmark |
menu | line.3.horizontal |
search | magnifyingglass |
settings | gearshape |
user | person |
home | house |
mail | envelope |
bell | bell |
heart | heart |
star | star |
plus | plus |
minus | minus |
edit | pencil |
trash | trash |
share | square.and.arrow.up |
download | arrow.down.circle |
upload | arrow.up.circle |
camera | camera |
image | photo |
lock | lock |
unlock | lock.open |
eye | eye |
eye-off | eye.slash |
Include this helper in your Swift project:
extension Color {
init(hex: String) {
let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int: UInt64 = 0
Scanner(string: hex).scanHexInt64(&int)
let a, r, g, b: UInt64
switch hex.count {
case 3:
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6:
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8:
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(a, r, g, b) = (1, 1, 1, 0)
}
self.init(
.sRGB,
red: Double(r) / 255,
green: Double(g) / 255,
blue: Double(b) / 255,
opacity: Double(a) / 255
)
}
}
Sources/
Theme/
ColorTheme.swift # From .pen variables
Typography.swift # Font styles
Components/
ButtonPrimary.swift # From reusable components
InputField.swift
Card.swift
Views/
LoginView.swift # From frames/screens
DashboardView.swift
TextField, Button over custom when possiblenpx claudepluginhub kjetilge/kjetil-claude-marketplace --plugin pencil-design-toolsConverts 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.
Translates between Figma designs and SwiftUI code in both directions: design-to-code and code-to-design. Routes to direction-specific reference docs.
Converts Claude HTML/CSS prototypes (via design URL or .tar.gz) to single self-contained SwiftUI View files in active Xcode workspaces. Generates code, builds, previews, and visually diffs for layout fidelity.