A powerful Figma plugin that automatically exports design tokens (strings, colors & typography) to GitHub repositories with support for Android, iOS, Flutter, and Kotlin Multiplatform projects.
- π± Multi-Platform Support: Export to Android XML, iOS Localizable.strings, and Flutter ARB
- π 30+ Languages: Built-in support for major world languages
- π Multi-Mode Variables: Export all language modes in one click
- π€ Android: XML
colors.xml+ Jetpack ComposeColor.kt - π iOS: UIKit/SwiftUI color extensions with hex initializers (generated automatically)
- π¦ Flutter: Dart color constants with
Color.fromARGB() - π― Full RGBA Support: Alpha channel preserved across all platforms
- π Light/Dark Theming: Export all color modes as separate files using
{mode}placeholder
- π€ Android Compose:
Typography.ktwith TextStyle definitions and custom font family support - π Android XML:
styles.xmlwith TextAppearance styles includingfontFamily - π iOS: SwiftUI
Font/ UIKitUIFontextensions with proper custom font handling - π¦ Flutter:
TextStyleconstants with font weights, sizes, and line height ratios - π Comprehensive: fontSize, fontWeight, fontFamily, letterSpacing, lineHeight
- π Automated PR Creation: Creates pull requests automatically
- π± Multi-Platform Export: Export Android + iOS + Flutter in a single PR
- πΏ Configurable Branches: Custom branch names and PR titles
- π Non-Destructive Updates: Updates existing branches without deleting PR review comments
- πΎ Settings Persistence: Save your configuration for quick exports
- π Secure: Uses GitHub Personal Access Tokens
Search for "Design System Sync" in the Figma Community plugins.
Direct Link: Design System Sync on Figma Community
- Clone this repository:
git clone https://github.com/ZeyadAbdullah679/design-system-sync.git
cd design-system-sync- Install dependencies:
npm install- Build the plugin:
npm run build- Import to Figma:
- Open Figma Desktop
- Go to
PluginsβDevelopmentβImport plugin from manifest - Select the
manifest.jsonfile from this project
Create string variables in Figma with different modes for each language:
Collection: "App Strings"
βββ Mode: English (default)
βββ Mode: Arabic
βββ Mode: Spanish
Variables:
βββ app_title = "My App" / "ΨͺΨ·Ψ¨ΩΩΩ" / "Mi App"
βββ welcome_message = "Welcome!" / "Ω
Ψ±ΨΨ¨Ψ§!" / "Β‘Bienvenido!"
βββ button_continue = "Continue" / "Ω
ΨͺΨ§Ψ¨ΨΉΨ©" / "Continuar"
Create color variables in Figma. For theming, use multiple modes:
Collection: "Brand Colors"
βββ Mode: Light
βββ Mode: Dark
Variables:
βββ primary = #6200EE / #BB86FC
βββ background = #FFFFFF / #121212
βββ surface = #F5F5F5 / #1E1E1E
βββ text = #000000 / #FFFFFF
βββ error = #B00020 / #CF6679
Create text styles in Figma with your typography system:
Text Styles:
βββ Headline Large (32pt, Bold, Inter)
βββ Headline Medium (24pt, SemiBold, Inter)
βββ Body Large (16pt, Regular, Inter)
βββ Body Medium (14pt, Regular, Inter)
βββ Label Small (12pt, Medium, Inter)
βββ Caption (10pt, Regular, Inter)
-
Get a GitHub Personal Access Token:
- Go to GitHub β Settings β Developer settings β Personal access tokens
- Click "Generate new token (classic)"
- Select scope:
repo(Full control of private repositories) - Copy the token (starts with
ghp_)
-
In the plugin, enter:
- GitHub Username
- Repository Name
- Base Branch (main/development)
- Personal Access Token
-
Click "Test" to verify connection
-
Click "Save" to persist settings
Select what you want to export:
- β Strings: Localization strings for multi-language support
- β Colors: Design tokens for consistent theming
- β Fonts: Typography styles for text consistency
Select one or more platforms:
- β Android/KMP: XML resources + Jetpack Compose
- β iOS: SwiftUI / UIKit
- β Flutter: Dart
You can select multiple platforms to export everything in a single PR.
- Customize file paths (defaults work for most projects)
- Set branch name and PR title in the export section
- Click "Load Variables from Figma"
- Review the stats
- Click "Export to GitHub"
- Review the automated pull request! π
If your Figma color variables have multiple modes (e.g., "Light" and "Dark"), you can export each mode as a separate file using the {mode} placeholder in file paths:
Android: values/{mode}/colors.xml β values/light/colors.xml, values/dark/colors.xml
iOS: Theme/Colors_{mode}.swift β Theme/Colors_light.swift, Theme/Colors_dark.swift
Flutter: lib/theme/colors_{mode}.dart β lib/theme/colors_light.dart, lib/theme/colors_dark.dart
If your path does not contain {mode}, only the first mode (base theme) is exported β backward compatible with single-mode setups.
Strings XML:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_title">My App</string>
<string name="welcome_message">Welcome!</string>
</resources>Colors XML:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary">#FF6200EE</color>
<color name="secondary">#FF03DAC6</color>
</resources>Compose Colors:
package com.example.theme
import androidx.compose.ui.graphics.Color
val Primary = Color(0xFF6200EE)
val Secondary = Color(0xFF03DAC6)Compose Typography:
package com.example.theme
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
val HeadlineLarge = TextStyle(
fontFamily = InterFontFamily,
fontSize = 32.sp,
fontWeight = FontWeight(700),
lineHeight = 38.4.sp
)XML Typography (styles.xml):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TextAppearance.HeadlineLarge">
<item name="android:fontFamily">Inter</item>
<item name="android:textSize">32sp</item>
<item name="android:textFontWeight">700</item>
<item name="android:lineHeight">38sp</item>
</style>
</resources>Localizable.strings:
/* Localization strings generated from Figma */
"app_title" = "My App";
"welcome_message" = "Welcome!";
SwiftUI Colors (includes hex initializer):
import SwiftUI
// MARK: - Color Hex Initializer
extension Color {
init(hex: String, opacity: Double = 1.0) {
// ... hex parsing logic generated automatically
}
}
// MARK: - Design System Colors
extension Color {
static let primary = Color(hex: "#6200EE")
static let secondary = Color(hex: "#03DAC6")
static let overlay = Color(hex: "#000000", opacity: 0.5)
}SwiftUI Typography:
import SwiftUI
// MARK: - Typography Styles
extension Font {
static let headlineLarge = Font.custom("Inter", size: 32).weight(.bold)
static let bodyMedium = Font.system(size: 14, weight: .regular)
}UIKit Typography (custom font with fallback):
import UIKit
extension UIFont {
static let headlineLarge = UIFont(name: "Inter", size: 32) ?? UIFont.systemFont(ofSize: 32, weight: .bold)
static let bodyMedium = UIFont.systemFont(ofSize: 14, weight: .regular)
}ARB Strings:
{
"@@locale": "en",
"app_title": "My App",
"welcome_message": "Welcome!"
}Dart Colors:
import 'package:flutter/material.dart';
class AppColors {
static const Color primary = Color.fromARGB(255, 98, 0, 238);
static const Color secondary = Color.fromARGB(255, 3, 218, 198);
}Dart Typography:
import 'package:flutter/material.dart';
class AppTextStyles {
static const TextStyle headlineLarge = TextStyle(
fontFamily: 'Inter',
fontSize: 32,
fontWeight: FontWeight.w700,
height: 1.2,
);
}| Token Type | Path |
|---|---|
| Strings | shared/src/commonMain/composeResources/{lang}/strings.xml |
| Colors XML | shared/src/commonMain/composeResources/values/colors.xml |
| Compose Colors | shared/src/commonMain/kotlin/theme/Color.kt |
| Typography XML | shared/src/commonMain/composeResources/values/styles.xml |
| Compose Typography | shared/src/commonMain/kotlin/theme/Typography.kt |
| Token Type | Path |
|---|---|
| Strings | {lang}.lproj/Localizable.strings |
| Colors | Shared/Theme/Colors.swift |
| Typography | Shared/Theme/Typography.swift |
| Token Type | Path |
|---|---|
| Strings | lib/l10n/app_{lang}.arb |
| Colors | lib/theme/app_colors.dart |
| Typography | lib/theme/app_text_styles.dart |
Path Placeholders:
{lang}β Replaced with language code/folder (e.g.,values-ar,Base.lproj,app_en.arb){mode}β Replaced with color mode name (e.g.,light,dark) for multi-theme exports
All paths are fully customizable in the plugin UI.
Built-in mappings for 30+ languages including:
English, Arabic, Spanish, French, German, Italian, Portuguese, Russian, Chinese, Japanese, Korean, Dutch, Polish, Turkish, Swedish, Norwegian, Danish, Finnish, Greek, Hindi, Thai, Vietnamese, Indonesian, Malay, Czech, Hungarian, Romanian, Ukrainian, and more.
- "Failed to get base branch": Verify branch name and token permissions
- "Connection failed": Check token validity and internet connection
- "Path does not exist": Create folder structure first or adjust paths
- Strings paths must include
{lang}placeholder - For theming, include
{mode}in color paths to get per-mode files
- "No variables found": Create variables/text styles in Figma first
- Typography requires Text Styles (not just text layers)
- Colors require Color type variables (not solid paint fills)
src/
βββ plugin.ts # Entry point (Figma sandbox)
βββ types.ts # Shared type definitions
βββ constants.ts # Language mapping
βββ github.ts # GitHub PR workflow
βββ extractors/ # Figma API data extraction
β βββ colors.ts
β βββ typography.ts
βββ generators/ # Platform-specific code generation
β βββ strings.ts # Android XML, iOS strings, Flutter ARB
β βββ colors.ts # Color files for all platforms
β βββ typography.ts # Typography files for all platforms
βββ utils/ # Encoding, escaping, color conversion
β βββ encoding.ts
β βββ escaping.ts
β βββ colors.ts
β βββ network.ts
β βββ debug.ts
βββ ui/ # Plugin frontend
βββ ui.html
βββ ui.css
βββ ui.ts
npm install # Install dependencies
npm run build # Bundle src/ β code.js + ui.html via esbuild
npm run watch # Build with file watching
npm run typecheck # TypeScript type checking
npm test # Run tests
npm run test:coverage # Run tests with coverage
npm run lint # ESLintThe plugin includes 86+ tests covering:
- String parsing (Android XML, iOS Strings, Flutter ARB)
- Color conversion, generation, and multi-mode theming
- Typography generation with custom font handling
- GitHub API integration (branch create/update, PR creation)
- Encoding and escaping utilities
- Edge cases (prefix stripping, alpha channels, special characters)
npm test # Run all tests
npx jest tests/core/colorParsing.test.ts # Run a single test fileSet DEBUG_MODE = true in src/utils/debug.ts to enable console logging routed to the plugin UI.
- β¨ Multi-Platform Export: Select Android + iOS + Flutter and export all in a single PR
- β¨ Light/Dark Theming: Export all color modes as separate files with
{mode}placeholder - β¨ Configurable Branch & PR: Custom branch names, PR titles, and commit messages
- π Non-Destructive Branch Updates: Existing branches are updated via PATCH, preserving PR review comments
- π οΈ Modular Codebase: Refactored from 2 monolithic files into 15+ focused modules under
src/ - π οΈ esbuild Bundler: Replaced
tscwith esbuild for fast builds - π iOS Hex Initializer: Generated Swift code now includes the
Color(hex:)/UIColor(hex:)extension - π iOS Alpha Support: Colors with transparency correctly pass
opacity:/alpha:parameter - π iOS Custom Fonts:
Font.custom()preserves exact font names; UIKit usesUIFont(name:size:)with fallback - π Android XML fontFamily: Typography styles now include
android:fontFamily - π§ͺ 86+ tests with imports from source modules (no more duplicated test functions)
- β¨ Flutter platform support (ARB, Dart colors, TextStyle)
- β¨ Typography/Font Styles export for all platforms
- β¨ Extract text styles from Figma
- π¨ Enhanced UI with 3 export types
- β¨ Color variables support
- β¨ Android Compose & iOS color extensions
- π¨ Renamed to "Design System Sync"
- π Initial release with string export
- Issues: GitHub Issues
- Plugin: Figma Community
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Built with β€οΈ for the multi-platform development community.