A user should have a consistent experience whether they visit your website, open your iOS app, or use your desktop application. Cross-platform design systems ensure visual language, interaction patterns, and component behavior are consistent across every surface.
The Challenge
Each platform has its own:
- Rendering engine: CSS for web, UIKit/SwiftUI for iOS, Views for Android
- Interaction patterns: Hover vs touch, back button vs swipe
- Typography: System fonts differ across platforms
- Navigation: Tab bars, drawers, sidebars — conventions vary
- Component libraries: Different implementations for the same concept
Maintaining consistency across these differences requires a systematic approach.
Design Token Architecture
Tokens are the foundation of cross-platform consistency:
{
"color": {
"primary": { "$value": "#3b82f6" },
"secondary": { "$value": "#8b5cf6" },
"error": { "$value": "#ef4444" }
},
"spacing": {
"sm": { "$value": "8" },
"md": { "$value": "16" },
"lg": { "$value": "24" }
},
"radius": {
"sm": { "$value": "4" },
"md": { "$value": "8" },
"lg": { "$value": "16" }
},
"typography": {
"heading": {
"fontFamily": { "$value": "Inter" },
"fontSize": { "$value": "24" },
"fontWeight": { "$value": "700" }
}
}
}
These tokens transform into platform-specific formats:
- Web: CSS custom properties or Tailwind config
- iOS: Swift constants or asset catalogs
- Android: XML resources or Compose tokens
- React Native: JavaScript/TypeScript constants
Transformation Pipeline
Design tokens (JSON)
↓
Style Dictionary / Cobalt UI
↓
├── CSS custom properties (web)
├── Tailwind config (web)
├── Swift constants (iOS)
├── Kotlin constants (Android)
├── TypeScript constants (React Native)
└── Figma Tokens (design)
One source of truth generates all platform implementations.
Shared Component Libraries
React + React Native
Share component APIs between web and mobile:
// Shared component interface
interface ButtonProps {
label: string;
variant: 'primary' | 'secondary' | 'ghost';
size: 'sm' | 'md' | 'lg';
onPress: () => void;
disabled?: boolean;
}
// Web implementation (React)
export function Button({ label, variant, size, onPress, disabled }: ButtonProps) {
return (
<button
className={cn(buttonVariants({ variant, size }))}
onClick={onPress}
disabled={disabled}
>
{label}
</button>
);
}
// Mobile implementation (React Native)
export function Button({ label, variant, size, onPress, disabled }: ButtonProps) {
return (
<Pressable
style={[styles.base, styles[variant], styles[size]]}
onPress={onPress}
disabled={disabled}
>
<Text style={styles.label}>{label}</Text>
</Pressable>
);
}
Same API, platform-native implementation.
Tamagui
A cross-platform UI library for React and React Native that shares components and styles:
import { Button, Text, YStack } from 'tamagui';
// Same code runs on web and mobile
function MyComponent() {
return (
<YStack padding="$md" gap="$sm">
<Text fontSize="$heading">Hello</Text>
<Button theme="primary">Click me</Button>
</YStack>
);
}
NativeWind
Tailwind CSS for React Native. Write Tailwind classes that work on both platforms:
import { View, Text } from 'react-native';
function Card() {
return (
<View className="p-4 bg-white rounded-lg shadow-md">
<Text className="text-lg font-bold text-gray-900">Card Title</Text>
</View>
);
}
Platform-Specific Adaptations
Not everything should be identical. Respect platform conventions:
| Pattern | Web | iOS | Android |
|---|---|---|---|
| Navigation | Top navbar + sidebar | Tab bar (bottom) | Bottom navigation |
| Back action | Browser back button | Swipe right edge | System back button |
| Selection | Checkbox | Toggle switch | Checkbox |
| Loading | Skeleton or spinner | Activity indicator | Progress indicator |
| Alerts | Toast / modal | Native alert | Snackbar |
Figma to Code Pipeline
- Design in Figma: Use component variants and auto-layout
- Export tokens: Figma Tokens plugin exports to JSON
- Transform: Style Dictionary generates platform code
- Sync: CI pipeline detects changes and creates PRs
- Review: Developers review and merge design changes
Our Cross-Platform Approach
For clients who need web and mobile presence, we build shared design token systems from the start. Components share the same design language while respecting platform conventions. This keeps brands consistent and reduces the effort of maintaining parallel design systems.