Use Zeplin as a developer handoff layer above Figma — enhanced measurement overlays, multi-platform code generation, component documentation, Storybook integration, and team annotation workflows beyond Figma's built-in Dev Mode.
Figma Dev Mode provides excellent developer handoff for most teams. But Zeplin adds a layer of capability that some teams find essential: multi-platform code generation (the same design exports CSS, Swift, Kotlin, and Flutter), Connected Components linking design to Storybook stories, and structured component documentation with markdown support.
Understanding Zeplin helps you decide whether your team needs it, and helps you use it effectively if your team already subscribes. For teams working on cross-platform products (web + iOS + Android), Zeplin's multi-platform code generation is its clearest value proposition.
Zeplin works as a layer above Figma — designers publish artboards and components from Figma to Zeplin, where developers access enhanced inspection.
Setup workflow:
What Zeplin imports from Figma:
Zeplin project structure:
1Zeplin Project: DevBootstrap
2├── Screens
3│ ├── Home / Desktop
4│ ├── Course Detail / Desktop
5│ ├── Course Detail / Mobile
6│ └── Checkout / Steps 1-4
7├── Components
8│ ├── Button (all variants)
9│ ├── Course Card
10│ └── Input
11└── Styleguide
12 ├── Colors (from Figma styles)
13 ├── Text styles
14 └── SpacingUpdating Zeplin after Figma changes:
Zeplin diff view (very useful for developers):
Zeplin's primary advantage over Figma Dev Mode is multi-platform code generation from the same design file. Web, iOS, and Android developers all get platform-appropriate code from a single design source.
Selecting code output platform in Zeplin:
Comparison for a button element:
Zeplin CSS output:
1.btn-primary {
2 display: flex;
3 flex-direction: row;
4 align-items: center;
5 justify-content: center;
6 padding: 0.875rem 1.5rem;
7 border-radius: 0.5rem;
8 background-color: #2563eb;
9 font-family: Inter, sans-serif;
10 font-size: 0.9375rem;
11 font-weight: 600;
12 line-height: 1.467;
13 color: #ffffff;
14}Zeplin Swift output (UIKit):
1let button = UIButton()
2button.backgroundColor = UIColor(red: 37/255, green: 99/255, blue: 235/255, alpha: 1)
3button.layer.cornerRadius = 8
4button.contentEdgeInsets = UIEdgeInsets(top: 14, left: 24, bottom: 14, right: 24)
5
6let attributedTitle = NSAttributedString(
7 string: "Enroll now",
8 attributes: [
9 .font: UIFont(name: "Inter-SemiBold", size: 15)!,
10 .foregroundColor: UIColor.white
11 ]
12)
13button.setAttributedTitle(attributedTitle, for: .normal)Zeplin Kotlin output (Android):
1// In your layout XML (Zeplin exports both Kotlin and XML)
2// XML:
3<com.google.android.material.button.MaterialButton
4 android:layout_width="wrap_content"
5 android:layout_height="48dp"
6 android:paddingStart="24dp"
7 android:paddingEnd="24dp"
8 android:text="Enroll now"
9 android:textSize="15sp"
10 android:textColor="@color/white"
11 app:backgroundTint="@color/blue_600"
12 app:cornerRadius="8dp" />Zeplin Flutter output:
1ElevatedButton(
2 onPressed: () {},
3 style: ElevatedButton.styleFrom(
4 backgroundColor: Color(0xFF2563EB),
5 shape: RoundedRectangleBorder(
6 borderRadius: BorderRadius.circular(8),
7 ),
8 padding: EdgeInsets.symmetric(horizontal: 24, vertical: 14),
9 textStyle: TextStyle(
10 fontFamily: 'Inter',
11 fontSize: 15,
12 fontWeight: FontWeight.w600,
13 ),
14 ),
15 child: Text('Enroll now'),
16)When this matters:
Zeplin Connected Components is a feature that links Zeplin design components to their source code files and Storybook stories. When a developer clicks a Button in Zeplin, they see a link to Button.tsx and the Storybook Button story.
Setup:
1# Install Zeplin CLI
2npm install -g @zeplin/cli
3
4# Create zeplin.json in project rootzeplin.json configuration:
1{
2 "projects": ["YOUR_ZEPLIN_PROJECT_ID"],
3 "styleguides": [],
4 "components": [
5 {
6 "path": "src/components/ui/Button.tsx",
7 "zeplinNames": [
8 "Button / Primary",
9 "Button / Secondary",
10 "Button / Ghost"
11 ],
12 "storybook": {
13 "kind": "Components/Button",
14 "stories": ["Primary", "Secondary", "Ghost", "AllVariants"]
15 }
16 },
17 {
18 "path": "src/components/course/CourseCard.tsx",
19 "zeplinNames": ["Course Card / Default", "Course Card / Enrolled"],
20 "storybook": {
21 "kind": "Course/CourseCard",
22 "stories": ["Default", "Enrolled", "Completed"]
23 }
24 }
25 ]
26}1# Connect components to Zeplin
2zeplin connect
3
4# Output: connecting 2 components to Zeplin...
5# ✓ Button linked: 3 Zeplin components → Button.tsx + 4 stories
6# ✓ CourseCard linked: 2 Zeplin components → CourseCard.tsx + 3 storiesWhat developers see in Zeplin after linking:
This is the most powerful Zeplin feature: designers see the code, developers see the design, and both reference the same source of truth.
Figma Dev Mode and Zeplin overlap significantly. The right choice depends on team structure, platform needs, and budget.
Figma Dev Mode strengths:
Zeplin strengths:
Decision framework:
1Is your product web-only?
2 YES → Figma Dev Mode is sufficient
3 NO → Do you have iOS or Android developers?
4 YES → Zeplin's multi-platform code generation adds value
5 NO → Figma Dev Mode is sufficient
6
7Is your design system large (50+ components)?
8 YES → Zeplin Connected Components helps developers find implementations
9 NO → Figma Dev Mode is sufficient
10
11Do you need strict visual diffing between versions?
12 YES → Zeplin's diff view is valuable
13 NO → Figma version history + named versions is sufficientCost comparison (2026):
1Figma Dev Mode:
2 Available in Figma Professional plan ($45/editor/month)
3 Developers (viewers): FREE
4 Net developer cost: $0
5
6Zeplin:
7 Team plan: approximately $15/seat/month (all users)
8 10 users: $150/month in addition to Figma cost
9 Net additional cost: $150-200/month for most teamsRecommendation for 2026:
Publishing a course card component from Figma to Zeplin and extracting platform-specific code for web, iOS, and Android teams.
1/* ZEPLIN HANDOFF: Course Card Component
2 Published from Figma to Zeplin project 'DevBootstrap'
3 Platforms: Web (CSS), iOS (Swift), Android (Kotlin)
4
5=== WEB TEAM: CSS from Zeplin ===
6
7/* Zeplin CSS output for Course Card: */
8.course-card {
9 display: flex;
10 flex-direction: column;
11 overflow: hidden;
12 background-color: #ffffff;
13 border: 1px solid #e5e7eb;
14 border-radius: 0.75rem; /* Zeplin converts 12px to rem */
15 width: 17.5rem; /* 280px */
16}
17
18.course-card__thumbnail {
19 width: 100%;
20 height: 10rem; /* 160px */
21 object-fit: cover;
22}
23
24.course-card__body {
25 display: flex;
26 flex-direction: column;
27 gap: 0.5rem;
28 padding: 1rem;
29}
30
31.course-card__title {
32 font-family: Inter, sans-serif;
33 font-size: 1.125rem;
34 font-weight: 600;
35 line-height: 1.444;
36 color: #111827;
37}
38
39/* Web developer adds: hover state, transition, responsive */
40.course-card { transition: box-shadow 200ms ease; }
41.course-card:hover { box-shadow: 0 8px 24px rgb(0 0 0 / 0.1); }
42
43=== iOS TEAM: Swift from Zeplin ===
44/* Zeplin Swift output (UIKit): */
45
46struct CourseCardView: UIView {
47 let thumbnailView: UIImageView = {
48 let iv = UIImageView()
49 iv.contentMode = .scaleAspectFill
50 iv.clipsToBounds = true
51 iv.heightAnchor.constraint(equalToConstant: 160).isActive = true
52 return iv
53 }()
54
55 let titleLabel: UILabel = {
56 let label = UILabel()
57 label.font = UIFont(name: "Inter-SemiBold", size: 18)
58 label.textColor = UIColor(rgb: 0x111827)
59 label.numberOfLines = 2
60 return label
61 }()
62
63 override init(frame: CGRect) {
64 super.init(frame: frame)
65 layer.cornerRadius = 12
66 layer.borderWidth = 1
67 layer.borderColor = UIColor(rgb: 0xE5E7EB).cgColor
68 backgroundColor = .white
69 // ... setup stackView with thumbnail + body
70 }
71}
72
73=== ANDROID TEAM: Kotlin + XML from Zeplin ===
74/* Zeplin Kotlin/XML output: */
75
76<!-- res/layout/view_course_card.xml -->
77<com.google.android.material.card.MaterialCardView
78 android:layout_width="280dp"
79 android:layout_height="wrap_content"
80 app:cardCornerRadius="12dp"
81 app:cardElevation="0dp"
82 app:strokeWidth="1dp"
83 app:strokeColor="@color/border_default">
84
85 <LinearLayout
86 android:orientation="vertical">
87
88 <ImageView
89 android:layout_width="match_parent"
90 android:layout_height="160dp"
91 android:scaleType="centerCrop"
92 app:srcCompat="@drawable/placeholder_course" />
93
94 <LinearLayout
95 android:orientation="vertical"
96 android:padding="16dp"
97 android:gap="8dp">
98
99 <TextView
100 android:textSize="18sp"
101 android:fontFamily="@font/inter_semibold"
102 android:textColor="@color/text_primary"
103 android:maxLines="2"
104 android:ellipsize="end" />
105 </LinearLayout>
106 </LinearLayout>
107</com.google.android.material.card.MaterialCardView>
108
109=== CONNECTED COMPONENT LINK ===
110
111Developers clicking 'Course Card / Default' in Zeplin see:
112 Implementation: src/components/course/CourseCard.tsx
113 Storybook: /story/course-coursecard--default
114 Android: app/src/main/java/com/.../CourseCardView.kt
115 iOS: CourseCardView.swift
116
117/* All four platform teams sharing the same design source.
118 No value divergence. One update in Figma → republish → all platforms updated. */The cross-platform example shows Zeplin's primary value: the same Figma artboard generates CSS for web, UIKit Swift for iOS, MaterialCardView Kotlin for Android, and could also generate Flutter Dart. Without Zeplin, each platform team reads the same Figma file but translates values differently — resulting in subtle inconsistencies (iOS uses 11pt font while web uses 18px) that the designer cannot catch without reviewing three separate implementations. The Connected Components link at the bottom shows the most powerful feature: clicking any platform's component in Zeplin shows a link to that platform's implementation file.
The next lesson covers Stakeholder Communication — how to present design decisions to non-technical stakeholders, manage design feedback from multiple stakeholders, and build consensus without design by committee.
Your progress is saved in this browser, on this device only.