Change what your users see.
flutter_skin is a runtime skin engine for Flutter. It lets you define your app's theme (currently color scheme) remotely — in production, on real user devices, without shipping any updates.
You push a new skin from the FSkin dashboard. Every user running your app sees the change instantly — no rebuild, no review cycle, no restart required.
Theming system in mobile apps is super powerful but static. Once your app ships, its colors are locked in the binary. Changing a single button color means a full release cycle:
Code change → Build → Review → App Store approval → User update
flutter_skin cycle:
Dashboard publish → CDN update → Users see new colors (~2 seconds)
You update the settings, your users see the change instantly.
Fully compliant with App Store and Google Play policies, since the app itself isn't changing, same codebase but different configuration. Perfect for:
- White-label apps with multiple brands
- Seasonal themes (holidays, events)
- Emergency fixes
Sign up at app.fskin.dev, create a project, and copy your API key.
dependencies:
flutter_skin: ^0.0.2flutter pub getimport 'package:flutter_skin/flutter_skin.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterSkin.init(
apiKey: 'fsk_your_api_key_here',
);
runApp(const MyApp());
}class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
theme: FlutterSkin.toThemeData(),
home: const HomeScreen(),
);
}
}That's it your app is FlutterSkin now.
No wrapper needed nor additional setup, perfect for quick integration on built projects.
The current skin model supports a full Material-compatible color scheme:
| Token | Description |
|---|---|
skin.colors.primary |
Main brand color |
skin.colors.secondary |
Accent / secondary color |
skin.colors.background |
Page background |
skin.colors.surface |
Card / container background |
skin.colors.error |
Error states |
skin.colors.onPrimary |
Text/icon on primary color |
skin.colors.onSecondary |
Text/icon on secondary color |
skin.colors.onBackground |
Text/icon on background |
skin.colors.onSurface |
Text/icon on surface |
skin.colors.onError |
Text/icon on error color |
skin.colors.brightness |
Brightness.light or Brightness.dark |
These map directly to Flutter's ColorScheme — FlutterSkin.toThemeData() converts them automatically.
Upcoming versions: more tokens and more customization
The current skin model supports dynamic fonts and typography styles. You can setup a font or google font for your skin and the package will automatically update the font and typography styles based on SSE updates.
You can define a custom font for your skin and the package will automatically update the font and typography
- Setup your font file in your project and define it in your
pubspec.yamlfile.
flutter:
fonts:
- family: CustomFont
fonts:
- asset: fonts/CustomFont-Regular.ttf- Add your custom font to your skin in the FSkin dashboard and publish it.
You can also define a google font for your skin and the package will automatically update the font and typography styles based on SSE updates.
- Add your google font to your skin in the FSkin dashboard and publish it.
- No other setup is required, the package will automatically fetch the google font and update the typography styles.
You can also define a fallback skin that the package will use if fetching the remote skin fails (e.g., no internet, server error). This ensures your app always has a consistent appearance, even without connectivity:
return MaterialApp(
title: 'My App',
theme: FlutterSkin.toThemeData(
fallbackTheme: ThemeData(
colorScheme: ColorScheme.light(
primary: Colors.blue,
secondary: Colors.green,
background: Colors.white,
surface: Colors.grey[200]!,
error: Colors.red,
onPrimary: Colors.white,
onSecondary: Colors.black,
onBackground: Colors.black87,
onSurface: Colors.black54,
onError: Colors.white,
),
),
),
home: const HomeScreen(),
);
This is what the package fetches from the FSkin:
{
"name": "default",
"version": 1,
"colors": {
"primary": "#6C63FF",
"secondary": "#FF6584",
"background": "#FFFFFF",
"surface": "#F9F9FB",
"error": "#EF4444",
"onPrimary": "#FFFFFF",
"onSecondary": "#000000",
"onBackground": "#0D0D0D",
"onSurface": "#1C1B1F",
"onError": "#FFFFFF",
"brightness": "light"
}
}Skins are created and published from the FSkin dashboard:
- Create multiple skins per project (currently just 2 since we're actively developing the dashboard, but more will come)
- Publish a skin with one click — all connected apps update within seconds
- Clone an existing skin as a starting point
- Flutter
>=3.0.0 - Dart
>=3.0.0
- 📖 Documentation: docs.fskin.dev
- 🎛️ Dashboard: app.fskin.dev
- 🐛 Issues: github.com/badrkouki/flutter_skin/issues
