A Flutter component library combining Naked UI interaction and accessibility with Mix styling.
This repository publishes two skills from its skills/ catalog:
using-remixhelps agents build Flutter interfaces with base Remix or the optional Fortal theme.building-remix-design-systemhelps agents create standalone design-system packages on Remix.
List the available skills without installing them:
npx skills add conceptadev/remix --listInstall both skills, or select one:
npx skills add conceptadev/remix
npx skills add conceptadev/remix --skill using-remix -yProject installs create a local agent-skills directory such as .agents/.
Contributors who do not want that directory in their checkout can install
globally or use a skill ephemerally:
npx skills add conceptadev/remix --skill using-remix -g -y
npx skills use conceptadev/remix@using-remixList installed skills and update them later:
npx skills ls
npx skills updateThis repository commits the project-scoped Mix skill and its lockfile so Codex and Claude Code use the same reviewed instructions. Install or refresh the canonical copy and Claude symlink with:
npx skills add conceptadev/mix --skill mix --agent codex --agent claude-code -yUpdate the committed installation from its locked project source with:
npx skills update mix --project -yfinal style = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.animate(AnimationConfig.spring(300.ms))
.onHovered(.color(Colors.blue.shade700));
RemixButton(
onPressed: () {},
label: 'Click me',
style: style,
);Or using callable styles:
final button = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.onHovered(.color(Colors.blue.shade700))
.animate(AnimationConfig.spring(300.ms));
button(
label: 'Click me',
onPressed: () {},
); // return RemixButton Widget.Add Remix to your project:
flutter pub add remixOr add it to your pubspec.yaml:
dependencies:
remix: ^1.0.0-beta.9A button with hover styling and animation:
import 'package:flutter/material.dart';
import 'package:remix/remix.dart';
class MyApp extends StatelessWidget {
final button = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.label(TextStyler().color(Colors.white));
@override
Widget build(BuildContext context) {
return WidgetsApp(
color: Colors.blue,
builder: (_, _) => Center(
child: button(
label: 'Click Me',
onPressed: () => debugPrint('Button pressed!'),
),
),
);
}
}Easily define how components should look in different interaction states.
final button = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.label(TextStyler().color(Colors.white))
.onHovered(.color(Colors.blue.shade700))
.onPressed(.scale(0.95));Make your button style smoothly animate when its state changes by chaining .animate() with your state-specific styles. You can use AnimationConfig.spring to get natural, spring-based motion.
final style = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.color(Colors.blue)
.borderRadius(.all(const Radius.circular(8)))
.animate(AnimationConfig.spring(300.ms))
.onHovered(.color(Colors.blue.shade700))
.onPressed(.scale(0.95));This example animates both the color on hover and the scale on press, creating a smooth interactive experience for your users.
See the Mix repository for keyframe and phase animation APIs.
Create base styles and extend them to build variants:
final baseButtonStyle = ButtonStyler()
.padding(.horizontal(16))
.padding(.vertical(10))
.borderRadius(.all(const Radius.circular(8)));
final primaryButton = baseButtonStyle
.color(Colors.blue)
.label(TextStyler().color(Colors.white));
final destructiveButton = baseButtonStyle
.color(Colors.red)
.label(TextStyler().color(Colors.white));Remix ships no theme of its own. If you want a polished, Radix Themes-inspired starting point instead of authoring every style yourself, initialize the application-owned Fortal preset:
flutter pub add dev:remix_cli
dart run remix_cli:remix init --prefix Fortal --preset fortal
dart run remix_cli:remix add buttonIt copies FortalScope, the token system, fortal*Style() recipes, and the
components you add into your application.
See the Fortal documentation to get started.
Remix composes inside your existing Flutter host. It does not require a
MaterialApp, Scaffold, or Remix-owned application wrapper.
| UI | Caller provides | Compatible hosts |
|---|---|---|
Ordinary Remix* widgets |
The inherited Flutter services used by the widget subtree | Material, Cupertino, Widgets, and router-based hosts |
| Widgets styled by the Fortal preset | The preset's token scope, in addition to the widget's normal Flutter services | Any Flutter host |
| Menu, select, popover, and tooltip | An Overlay |
Any host exposing an overlay; use Overlay.wrap when no Navigator is needed |
showRemixDialog and showRemixAlertDialog |
A Navigator |
Any host with a caller-owned navigator |
For a portal-based interface without routing, provide only an overlay:
import 'package:flutter/widgets.dart';
import 'package:remix/remix.dart';
Widget buildPortalHost() {
return WidgetsApp(
color: const Color(0xFFFFFFFF),
builder: (_, _) => Overlay.wrap(
child: Center(
child: RemixMenu<String>(
trigger: const RemixMenuTrigger(label: 'Actions'),
items: const [
RemixMenuItem(value: 'share', label: 'Share'),
],
),
),
),
);
}A MaterialApp, CupertinoApp, WidgetsApp, or router with routing configured
commonly provides a Navigator and its overlay already. Dialog helpers push
routes, so their calling context must be below that caller-owned Navigator.
Available components:
- Button - Clickable actions with full styling control
- IconButton - Icon-based actions
- Switch - Toggle controls
- Toggle - Two-state on/off buttons
- Checkbox - Multiple selection
- CheckboxGroup - Coordinated multiple selection with composable checkbox visuals
- Radio - Single selection from a group
- Slider - Continuous value selection
- TextField - Text input with validation support
- TextArea - Multiline text input with safe auto-growing defaults
- Select - Dropdown selection with keyboard navigation
- Avatar - User avatars and images
- Badge - Status indicators and labels
- Card - Content containers
- DataList - Label/value metadata lists with a shared label column
- DataTable - Controlled tables with shared column headers, sorting, selection, and pagination
- Divider - Visual separators
- Progress - Progress indicators
- Skeleton - Loading placeholders that mirror their content
- Spinner - Loading states
- Tabs - Tabbed navigation
- Accordion - Collapsible content sections
- Disclosure - A standalone trigger and inline expandable panel
- Menu - Context menus and dropdowns
- SegmentedControl - Equal-segment controlled single selection
- Dialog - Modal dialogs
- Tooltip - Contextual help
- Callout - Highlighted information blocks
Remix is ideal for:
- Teams building custom design systems who need full control over component appearance
- Developers requiring complex state management with multiple variants and interaction states
- Applications needing consistent styling across dozens of components
Live examples:
- Fortal dashboard — a polished product dashboard with responsive layouts, charts, data, and live theme controls.
- Component catalog — the Widgetbook catalog for reviewing Remix and Fortal components, variants, and states.
Check out apps/dashboard, apps/demo, and the per-package examples in
packages/remix/example and packages/remix_fortal/example for complete working examples demonstrating:
- Component usage patterns
- Style composition techniques
- Design system implementation
- Advanced customization
