Flutterware

pub package MIT license

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.

The studio drawing a test of the demo coffee shop as a flow of phone
screenshots, a coding agent's session reporting the feature it was asked for
with the two screens it changed, and the commands a terminal takes

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
The demo's menu rendered on an iPhone 16 frame, with the list of its screens beside it A test of the demo drawn as a flow of phone screenshots
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 rows of finished store images The translations table, each key beside a picture of it on screen
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
The steps an agent took through the demo on an iPhone, one of them open A branch's comparison: the tests whose screens changed, one open step by step
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
A branch's files, the ones the project pins first, one open on its diff A Dart server's requests, one open on its queries, an N+1 flagged
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
The launcher icon panel: the demo's Android icons in each mask shape, and its themed icon on a home screen The splash panel: every launch surface a config produces, on Android and iOS, in light and in dark
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, and Device(...) 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 bundle and 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 main so the app can be inspected and driven over the VM service — tree, logs, errors, images, and the ext.flutterware.act transaction.
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.
scene_authoring
The scene/motion authoring core — the vocabulary a generated .scene.dart is 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.