Fetching latest headlinesโ€ฆ
I built a remote skin engine for Flutter
NORTH AMERICA
๐Ÿ‡บ๐Ÿ‡ธ United Statesโ€ขJune 28, 2026

I built a remote skin engine for Flutter

0 views0 likes0 comments
Originally published byDev.to

Every one of us has been here.

The designer opens Figma and changes the primary color from #6C63FF to #5B52E8. A small update (they think).

Our release cycle: create a branch, update the color, build, test, submit to App Store, wait for store review, for just a hex code.

This is the tax Flutter developers pay for a compile-time theming system. It's powerful and type-safe and beautiful โ€” and completely frozen the moment your app ships.

flutter_skin

flutter_skin is a runtime skin engine. Instead of hardcoding your color values, you define them as named tokens. Those tokens are managed from a dashboard and delivered to your app.
When you publish a new skin, every connected device updates instantly.

How it works in 2 lines

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await FlutterSkin.init(apiKey: 'fsk_your_key_here');
  runApp(const MyApp());
}
// In your MaterialApp:
theme: FlutterSkin.toThemeData()

That's the integration. FlutterSkin.init() fetches the active skin from the FSkin backend and opens a persistent SSE connection. From that point, any skin you publish reaches the app in about 2 seconds.

The live update architecture

Here's what happens end to end when you click Publish:

Dashboard: click Publish
        โ†“
Skin marked active in PostgreSQL
        โ†“
Supabase Realtime detects the UPDATE on skins table
        โ†“
Node.js backend receives the Realtime event
        โ†“
Backend writes SSE event to all connected Flutter clients
        โ†“
flutter_skin package receives the flag
        โ†“
Package re-fetches active skin from CDN
        โ†“
A stream emits new SkinTokens
        โ†“
setState() โ†’ MaterialApp rebuilds โ†’ app repaints

Total time: ~1โ€“2 seconds. No polling. No App Store. No user action.

The full MaterialApp setup

To react to live updates, wrap your app in a StatefulWidget:

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    FlutterSkin.onSkinChanged.listen((_) {
      if (mounted) setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: FlutterSkin.toThemeData(),
      home: const HomePage(),
    );
  }
}

What's available today

The alpha supports color tokens โ€” full Material ColorScheme mapping:

  • primary, secondary, background, surface, error
  • All the on* counterparts
  • brightness for light/dark

The dashboard (app.fskin.dev) gives you:

  • Project management
  • Skin editor with JSON view
  • Team collaboration with role-based permissions
  • API key management (auto-generated per project)
  • Publishing with confirmation + version history

A lot of cool features still coming

Links

It's still on alpha track.
I'd love feedback from anyone who tries it โ€” bug reports, feature requests.
don't forget to thumbs up our package on pub.dev ๐Ÿฅธ ๐Ÿ‘€.

Comments (0)

Sign in to join the discussion

Be the first to comment!