Flutterware
A desktop studio for your Flutter project, with the same tools for your coding agent.
Live previews, widget tests that picture every step, store screenshots, and your app on a device you can drive. All of it also runs from the terminal.
Open the web demo to look around before installing anything. It is the studio itself, compiled for the web and opened on the demo app, a small coffee shop: the previews run live in the page, and every other tool shows what it found on a recorded run of the app. Nothing in it can change.

Try it on your machine
Clone the demo, the coffee shop app with every tool turned on, and start the studio:
git clone https://github.com/flutterware/flutterware_example
cd flutterware_example
dart run flutterware
The first launch builds the studio, so give it a minute.
You need Flutter 3.47 or newer. Live previews are macOS only for now; the rest also runs on Linux and Windows.
What's in it
| Previews | Scenarios |
|---|---|
![]() |
![]() |
Your @Preview widgets on a device frame, in a live engine. Change the device, the language or the theme, turn knobs, read the widget tree. |
Widget tests that keep a screenshot, the widget tree and the visible text of every step. The studio draws each run as a flow. |
| Store screenshots | Translations |
![]() |
![]() |
| App Store and Google Play images made from your tests, for every language, at the sizes each store asks for. The frame is a widget you write. | Every key in every language, next to a picture of where it appears. Missing and overlong strings are flagged. |
| Run | Comparison |
![]() |
![]() |
| Your app on a simulator, a phone or the desktop: its logs, network calls, widget tree and permissions, and every tap an agent made, step by step. | What a branch changed on screen. fw compare renders both sides from git and exports a page to link from the pull request. |
| Changes | Server |
![]() |
![]() |
| Your branch's diff with the files that matter listed first, and notes you can leave for your agent. | The requests your Dart backend handles, the SQL each one ran, and N+1 queries flagged. |
| Launcher icon | Splash screen |
![]() |
|
| Every app icon, as each platform will show it, and what's wrong with them. | What each platform shows at launch, read from the generated files. |
And the rest:
| Dependencies | Every package, the version pub picked, and which constraint asked for it. |
| Assets | What ends up in the bundle, how much it weighs, and which densities are missing. |
| Lints | Every rule your SDK knows, and whether your analysis_options.yaml uses it. |
| Dev stack | Start and stop the services your app needs while you work. |
| Database watch | Your app's SQLite database, readable while the app runs. |
| Scenes | Animations drawn with your own widgets and theme, exported to video. |
| Renders | A widget as SVG, PNG or PDF, from a script or from a server. |
Each tool has a guide in doc/.
Scenarios are widget tests
scenario('Around the shop', (s) async {
await s.pumpWidget(const ShopApp());
await s.tap(ShopKeys.getStarted);
await s.split({
'a cold brew': () async {
await s.tap('Cold brew');
await s.tap(ShopKeys.addToCart);
await s.tap(ShopKeys.placeOrder);
},
'the empty cart': () async {
await s.tap(ShopKeys.openCart);
},
});
});
flutter test runs this like any other test. Each step waits for the screen to
settle, then keeps what it showed. s.split replays the body once per branch,
so one scenario covers every path through a screen, and the flow in the
picture above is exactly that. Store images, translation pictures and branch
comparisons are all built from these runs.
Your agent gets the same tools
The first launch adds an MCP server to your project's .mcp.json. Through it, an
agent can render a preview to check a layout, run your scenarios and read what
each screen showed, or launch the app on a simulator and tap through it, with
every step it takes shown in the studio as it happens.
The same actions are on the command line:
alias fw='dart run flutterware'
fw run previews screenshot --entry='demo/shop.dart#shopMenu'
fw run scenarios run
fw run store export
Every action and option is listed in the capabilities reference.
Add it to your project
dart pub add flutterware
dart run flutterware
Flutterware runs on the Dart SDK you start it with (fvm dart run flutterware
works too) and never installs one of its own. The .mcp.json entry it writes
runs plain dart from your PATH, so if a version manager picks your SDK, edit
that entry to go through it (fvm dart run flutterware mcp). The first launch
creates tool/flutterware.dart, where you pick your tools:
import 'package:flutterware/plugins.dart';
const app = Pkg('.');
void main() => Flutterware.configure((fw) {
fw.use(Previews(packages: [.new(app)]));
fw.use(Scenarios(packages: [.new(app, languages: ['en', 'fr'])]));
fw.use(Dependencies(packages: [.new(app)]));
fw.use(Assets(packages: [.new(app)]));
});
It's a plain Dart file, so the analyzer checks it and your editor completes it.
For a monorepo, declare one Pkg per package and give each tool the ones it
applies to. The demo's config is
one app's; this repo's covers a workspace of several
packages.
Libraries
The package also ships libraries your app and tests can import. They work without the studio.
| Library | What it's for |
|---|---|
flutter_test.dart |
Everything in package:flutter_test, plus the scenario API. Swap the import and existing tests still compile. |
previews.dart |
PreviewShell for theme or locale switches in the previews toolbar, and context.knobs for knobs. |
store.dart |
What a store frame is written with: the shot it frames, and the status bar a capture lacks. |
devbar.dart |
A developer overlay inside your app: logs, network, feature flags, device frames. |
feature_flag.dart |
Feature flags you can read and override at runtime. |
router_outlet.dart |
Nested routing driven by the URL. |
server.dart |
Hooks for the server inspector, for Dart backends. |
ui_catalog.dart |
A browsable web page of your previews. |
plugins.dart |
What tool/flutterware.dart is written against. |
Get in touch
If you use flutterware, are trying it out, or wonder whether it would fit your project, we'd love to hear from you. Questions, ideas, or something that got in your way: write to hello@flutterware.dev.
Contributing
Issues and pull requests are welcome. CONTRIBUTING.md explains how to set up the repository.
Libraries
- ambient
- Lets app code declare motion that carries no information — a spinner, a shimmer, a pulsing dot — so a scenario photographs it standing still instead of waiting for it to stop. See Ambient.
- app_events
- Reporting what the app did — network calls, queries, analytics, logs.
- channels
- What a panel inside a running app declares, and how it serves it.
- channels_ui
- A PanelDescriptor drawn — the widgets the cockpit and the in-app overlay both use.
- comparison_report
- What a comparison wrote down, typed — the reader for
index.json. - devbar
- devbar_plugins/device_frame
- devbar_plugins/log_analytics
- devbar_plugins/log_network
- devbar_plugins/log_queries
- devbar_plugins/logger
- devbar_plugins/variables
- devices
- The device vocabulary the GUI's pickers,
fw, MCP and the scenario axes all speak —Devices.iphone16, andDevice(...)for a screen the table does not have. - drive
- The live half of the verb engine: scenarios' vocabulary executed against a
running app's real binding. For generated entrypoints and the guest
runtime, not for projects to import directly — a project's own tests want
package:flutterware/flutter_test.dart. - feature_flag
- flutter_test
- A strict superset of
package:flutter_test— everything re-exported 1:1, nothing hidden, plus the scenario API. An existing test file compiles with only its import changed. - plugins
- The flutterware plugin contract.
- previews
- What a project writes beside its
@Previews: a shell, and knobs. - previews_guest
- The guest's own plumbing — for generated code, not for projects.
- real_work
- Lets app code announce work that finishes on the real event loop, so a scenario's next verb waits for it rather than photographing a placeholder. See RealWork.
- reel
- Reading a scenario as a take, so a reel can be edited from it.
- render
- Render a widget's painted output as a real vector document.
- render_client
- The pure-Dart side of the render story: a RenderPool spawns resident
guests from a directory produced by
fw render bundleand invokes the app's render points fully typed. - render_contract
- The contract a render point is declared in: WidgetRender and DocumentRender descriptors, the wire-safe RenderOptions, and the result and warning types.
- router_outlet
- run_guest
- The run guest: what a generated run entrypoint wraps around an app's
mainso the app can be inspected and driven over the VM service — tree, logs, errors, images, and theext.flutterware.acttransaction. - scenarios_report
- What a scenario run wrote to disk, typed — the reader for
run.json. - scene
- The Flutter half of the scene system: motion playback and the bridges
between the pure authoring core (
package:flutterware/scene_authoring.dart) and Flutter's types. - The scene/motion authoring core — the vocabulary a generated
.scene.dartis built from, plus the pure document models and the motion runtime that evaluates them. - server
- Live inspection for Dart servers.
- store
- Composing a store screenshot — the frame a project draws around its app's own pixels.
- store_report
- What a store export wrote to disk, typed.
- translations
- Which translation key is on which screen, and a picture of it.
- ui_catalog
- The catalog page: a browsable index of your previews.
- world
- Worlds: several people on your real server, set up by a script.








