Skip to Content
DocsOverviewIntroduction

Introduction

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.

  • Compose, merge, and apply styles across widgets
  • Write maintainable styling definitions separate from widget code
  • Adapt styles conditionally based on interactions and context

Why Mix?

Flutter’s built-in styling works well for simple widgets, but as your app grows, common pain points emerge:

  • Style duplication: The same colors, spacing, and borders are repeated across widgets with no easy way to share them.
  • Tight coupling: Style logic lives inside build() methods, making it hard to reuse or test independently.
  • No conditional styling: Adapting styles for hover, press, dark mode, or breakpoints requires manual boilerplate.

Mix solves these by giving you a dedicated styling layer that stays consistent across widgets and files — without being tied to Material Design.

Goals and Principles

  • Define styles outside widgets while retaining BuildContext access
  • Reuse style definitions across your app for consistency
  • Adapt styles conditionally using variants (hover, dark mode, breakpoints)
  • Type-safe composability using Dart’s type system

Mix is designed to be a simple, thin layer over Flutter — widgets remain compatible and predictable. The API mirrors Flutter naming conventions for consistency, lets you build complex styles from reusable pieces through composability, and is fully extensible to fit your needs.

The Styler Pattern

Define styles using a fluent, chainable API with Styler classes:

final boxStyle = BoxStyler() .color(Colors.red) .size(100, 100) .borderRounded(10);
Resolving preview metadata...

Use this pattern when defining styles with direct values, chaining multiple properties, or building most common styling use cases. Learn more about styling.

For advanced composition with design tokens and directives, Mix also offers a Prop-based API using the .create() constructor:

final style = BoxStyler.create( color: Prop.token($primaryColor), padding: Prop.value(EdgeInsets.all(16)), );

Key Features

Dynamic Styling

Styles can adapt to interactions and context (hover, press, dark mode):

final buttonStyle = BoxStyler() .height(50) .borderRounded(25) .color(Colors.blue) .onHovered(.color(Colors.blue.shade700)) .onDark(.color(Colors.blue.shade200));

Learn more about Dynamic Styling.

Animation Support

Mix supports implicit animations, phase animations (multi-step sequences), and keyframe animations. Learn more in the Animations Guide.

Widget Modifiers

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. Learn more in the Widget Modifiers Guide.

Directives

Directives transform values (text casing, number scaling, color adjustments) at resolve time, keeping transformations inside the style so they survive merging. Learn more in the Directives Guide.

Design Tokens and Theming

Define reusable design tokens for colors, spacing, radii, and more:

final $primaryColor = ColorToken('primary'); final $borderRadius = RadiusToken('borderRadius'); final tokenDefinitions = <MixToken, Object>{ $primaryColor: Colors.blue, $borderRadius: Radius.circular(8), }; MixScope( tokens: tokenDefinitions, child: MyApp(), );

Learn more about Design Tokens and Theming.

Next Steps

Ready to start building? Head to the Getting Started guide to set up Mix and create your first styled widget. For a full reference of available widgets, see the Widgets section.