A styling system for Flutter
801
stars
1,847
commits
Dart
primary language
Sep 12, 2026
updated
Mix is a styling system for Flutter that separates style definitions from widget structure. It provides a composable, type-safe way to define and apply styles using a fluent API, design tokens, and context-aware variants.
The mix skill helps coding agents build
Flutter UI with Mix and maintain this monorepo's specs, generators, variants,
animations, tokens, modifiers, and packages.
List the repository's available skills without installing them:
npx skills add btwld/mix --list
Install the skill in the current project:
npx skills add btwld/mix --skill mix -y
Project installation creates a local agent-skills directory such as
.agents/. It is ignored because skills/ is the committed source
catalog. Install globally or invoke the skill ephemerally when you do not want
a project-local copy:
npx skills add btwld/mix --skill mix -g -y
npx skills use btwld/mix@mix
List installed skills and update them later:
npx skills ls
npx skills update
Flutter's built-in styling works well for simple widgets, but as your app grows, common pain points emerge:
build() methods, making it hard to reuse or test independently.Mix solves these by giving you a dedicated styling layer that stays consistent across widgets and files — without being tied to Material Design.
BuildContext access (resolved at build time, like Theme.of, with more flexibility)flutter pub add mix
Or in pubspec.yaml:
dependencies:
mix: <latest>
import 'package:mix/mix.dart';
final cardStyle = BoxStyler()
.size(240, 100)
.color(Colors.blue)
.alignment(.center)
.borderRounded(12)
.border(.color(Colors.black).width(1).style(.solid));
Box(
style: cardStyle,
child: StyledText(
'Hello Mix',
style: TextStyler().color(Colors.white).fontSize(18),
),
);
Define styles with a fluent, chainable API. Later attributes override earlier ones when chained:
final boxStyle = BoxStyler()
.height(100)
.width(100)
.color(Colors.purple)
.borderRounded(10);
// Compose from a base style
final base = BoxStyler()
.paddingX(16)
.paddingY(8)
.borderRounded(8)
.color(Colors.black);
final solid = base.color(Colors.blue);
WrapBox combines Box styling with Flutter's run-based Wrap layout:
final tagCloud = WrapBoxStyler()
.paddingAll(16)
.spacing(8)
.runSpacing(10)
.wrapAlignment(WrapAlignment.center);
WrapBox(style: tagCloud, children: tags);
alignment and clipBehavior configure the outer Box;
wrapAlignment and wrapClipBehavior configure the inner Wrap. The advanced
nested-style escape hatch is .flow(WrapStyler(...)).
Styles adapt to interactions and context in one place:
final buttonStyle = BoxStyler()
.height(50)
.borderRounded(25)
.color(Colors.blue)
.onHovered(.color(Colors.blue.shade700))
.onDark(.color(Colors.blue.shade200));
Built-in variants include onHovered, onPressed, onFocused, onDisabled, onDark, onLight, onBreakpoint, onMobile, onTablet, onDesktop, and platform/context variants.
Define reusable tokens and provide them via MixScope:
final $primary = ColorToken('primary');
final $spacingMd = SpaceToken('spacing.md');
MixScope(
colors: { $primary: Colors.blue },
spaces: { $spacingMd: 16.0 },
child: MyApp(),
);
final style = BoxStyler()
.color($primary())
.paddingAll($spacingMd());
.animate(AnimationConfig....).phaseAnimation(...)Some visual effects — opacity, clipping, visibility — aren't style properties. Modifiers let you declare widget wrappers inside your style so they stay composable and animatable.
Directives transform values (text casing, number scaling, color adjustments) at resolve time, keeping transformations inside the style so they survive merging.
| Package | Description |
|---|---|
| mix | Core styling framework |
| mix_annotations | Annotations for code generation |
| mix_generator | build_runner generator for specs |
| mix_lint | Custom linter rules |
| mix_winds | Utility-first styling inspired by Tailwind CSS |
Dart
95.5%
JavaScript
2.8%
HTML
1.1%
A styling system for Flutter
801
stars
1,847
commits
Dart
primary language
Sep 12, 2026
updated
Mix is a styling system for Flutter that separates style definitions from widget structure. It provides a composable, type-safe way to define and apply styles using a fluent API, design tokens, and context-aware variants.
The mix skill helps coding agents build
Flutter UI with Mix and maintain this monorepo's specs, generators, variants,
animations, tokens, modifiers, and packages.
List the repository's available skills without installing them:
npx skills add btwld/mix --list
Install the skill in the current project:
npx skills add btwld/mix --skill mix -y
Project installation creates a local agent-skills directory such as
.agents/. It is ignored because skills/ is the committed source
catalog. Install globally or invoke the skill ephemerally when you do not want
a project-local copy:
npx skills add btwld/mix --skill mix -g -y
npx skills use btwld/mix@mix
List installed skills and update them later:
npx skills ls
npx skills update
Flutter's built-in styling works well for simple widgets, but as your app grows, common pain points emerge:
build() methods, making it hard to reuse or test independently.Mix solves these by giving you a dedicated styling layer that stays consistent across widgets and files — without being tied to Material Design.
BuildContext access (resolved at build time, like Theme.of, with more flexibility)flutter pub add mix
Or in pubspec.yaml:
dependencies:
mix: <latest>
import 'package:mix/mix.dart';
final cardStyle = BoxStyler()
.size(240, 100)
.color(Colors.blue)
.alignment(.center)
.borderRounded(12)
.border(.color(Colors.black).width(1).style(.solid));
Box(
style: cardStyle,
child: StyledText(
'Hello Mix',
style: TextStyler().color(Colors.white).fontSize(18),
),
);
Define styles with a fluent, chainable API. Later attributes override earlier ones when chained:
final boxStyle = BoxStyler()
.height(100)
.width(100)
.color(Colors.purple)
.borderRounded(10);
// Compose from a base style
final base = BoxStyler()
.paddingX(16)
.paddingY(8)
.borderRounded(8)
.color(Colors.black);
final solid = base.color(Colors.blue);
WrapBox combines Box styling with Flutter's run-based Wrap layout:
final tagCloud = WrapBoxStyler()
.paddingAll(16)
.spacing(8)
.runSpacing(10)
.wrapAlignment(WrapAlignment.center);
WrapBox(style: tagCloud, children: tags);
alignment and clipBehavior configure the outer Box;
wrapAlignment and wrapClipBehavior configure the inner Wrap. The advanced
nested-style escape hatch is .flow(WrapStyler(...)).
Styles adapt to interactions and context in one place:
final buttonStyle = BoxStyler()
.height(50)
.borderRounded(25)
.color(Colors.blue)
.onHovered(.color(Colors.blue.shade700))
.onDark(.color(Colors.blue.shade200));
Built-in variants include onHovered, onPressed, onFocused, onDisabled, onDark, onLight, onBreakpoint, onMobile, onTablet, onDesktop, and platform/context variants.
Define reusable tokens and provide them via MixScope:
final $primary = ColorToken('primary');
final $spacingMd = SpaceToken('spacing.md');
MixScope(
colors: { $primary: Colors.blue },
spaces: { $spacingMd: 16.0 },
child: MyApp(),
);
final style = BoxStyler()
.color($primary())
.paddingAll($spacingMd());
.animate(AnimationConfig....).phaseAnimation(...)Some visual effects — opacity, clipping, visibility — aren't style properties. Modifiers let you declare widget wrappers inside your style so they stay composable and animatable.
Directives transform values (text casing, number scaling, color adjustments) at resolve time, keeping transformations inside the style so they survive merging.
| Package | Description |
|---|---|
| mix | Core styling framework |
| mix_annotations | Annotations for code generation |
| mix_generator | build_runner generator for specs |
| mix_lint | Custom linter rules |
| mix_winds | Utility-first styling inspired by Tailwind CSS |
Dart
95.5%
JavaScript
2.8%
HTML
1.1%