Flash by FlutterFlow

Flash hero banner

Flash is the AI-native, code-powered companion to FlutterFlow.

Use FlutterFlow's visual builder when it is the fastest tool for the job, and use Flash when you want reviewable code, local validation, repeatable changes, and agent-friendly workflows for new or existing apps.

Why Flash

Flash helps you:

  • build new FlutterFlow apps in Dart
  • make larger or more precise changes to existing FlutterFlow apps
  • validate locally before pushing changes
  • inspect existing pages, components, and resources before editing
  • keep FlutterFlow development in source control
  • give human developers and AI agents the same structured workspace

Flash is not a replacement for FlutterFlow's visual-first workflow. It complements it.

Think of the model as:

  • FlutterFlow for visual speed
  • Flash for code precision, repeatability, and AI-native workflows

Who Flash Is For

FlutterFlow developers

Flash is useful when you want to:

  • create reviewable changes instead of editor-only diffs
  • work faster on repetitive or structured changes
  • inspect a project before editing it
  • keep a reliable local workflow with validation, traces, and history

AI-driven builders

Flash is useful when you want to:

  • let agents work in a real code workspace instead of an opaque visual-only surface
  • generate or refine app changes in Dart
  • keep the workflow deterministic, reviewable, and easy to hand off
  • combine FlutterFlow's visual builder with agent-friendly development

Install

Install the CLI:

dart pub global activate flutterflow_flash_beta

If you want to use Flash as a library in a Dart package:

dart pub add flutterflow_flash_beta

Requirements:

  • Dart 3.7+
  • A FlutterFlow API key

Authentication options:

  • Put FF_API_KEY=<your-key> in .env
  • Or pass --api-key <your-key> to Flash commands

Example .env:

FF_API_KEY=your-key-here

Quickstart

Create a new Flash workspace:

flash init my-app
cd my-app
cp .env.example .env
dart pub get
dart test
flash validate flash/app.dart
flash run flash/app.dart --project-name "My App" --commit-message "Initial app"

That gives you a ready-to-edit workspace with:

  • flash/app.dart for building a new app
  • flash/brownfield_patch.dart for changes to an existing app
  • references/ with working DSL examples
  • patterns/ with existing-app helper patterns
  • tooling/ wrapper scripts for common flows
  • AGENTS.md and CLAUDE.md for agent handoff
  • generated_code/ snapshots for project-bound workspaces when flutterflow CLI is installed

Important: use flash/app.dart for the first push of a new app. After the project exists, switch to flash/brownfield_patch.dart and run flash refresh-context <project-id> before deeper work. Use --find-or-create only when retrying a run that may already have created the remote project.

If a new-project flash run fails before a successful push, Flash will not persist that project into .flash/workspace.json. It does not delete remote projects automatically, so a follow-up retry should use --find-or-create when you want to reuse a project that may already have been created upstream.

What The Workflow Looks Like

The core loop is simple:

  1. Build a new app or start from an existing FlutterFlow project.
  2. Describe the app or change in Dart.
  3. Run flash validate locally.
  4. Push with flash run.
  5. Continue iterating in Flash, in FlutterFlow, or both.

This makes Flash a good fit when you want to combine:

  • FlutterFlow's visual editing speed
  • code review and source control
  • repeatable automation
  • AI-assisted development

Build A New App

Here is a small but real Flash app definition:

import 'package:flutterflow_flash_beta/flutterflow_flash.dart';

void buildStarterApp(App app) {
  app.themeColor('primary', 0xFF0B57D0);
  app.themeColor('primaryBackground', 0xFFF7F9FC);
  app.primaryFont('Inter');

  app.page(
    'StarterPage',
    route: '/',
    isInitial: true,
    description: 'Simple starter page for a new Flash app.',
    body: Scaffold(
      appBar: AppBar(title: 'Flash Demo'),
      body: Container(
        padding: 24,
        child: Column(
          spacing: 16,
          crossAxis: CrossAxis.start,
          children: [
            Text('Build FlutterFlow apps with Dart', style: Styles.headlineSmall),
            Text(
              'Flash makes FlutterFlow changes reviewable, repeatable, and agent-friendly.',
              style: Styles.bodyMedium,
              color: Colors.secondaryText,
            ),
            Button(
              'Show Snackbar',
              width: double.infinity,
              onTap: Snackbar('Flash is wired correctly.'),
            ),
          ],
        ),
      ),
    ),
  );
}

Run it with:

flash validate flash/app.dart
flash run flash/app.dart --project-name "Flash Demo" --commit-message "Create starter page"

Work On An Existing FlutterFlow App

Flash is also built for existing apps, whether you are making focused changes or adding larger new flows.

Start from an existing project:

flash init my-edits --project <project-id>
cd my-edits
cp .env.example .env
dart pub get
flash inspect <project-id> --page HomePage
flash validate flash/brownfield_patch.dart --project-id <project-id>
flash run flash/brownfield_patch.dart --project-id <project-id> --commit-message "Update HomePage"

Useful existing-app commands:

  • flash inspect <project-id> to get the default human-readable project summary, or add --page, --component, --dsl-json, --tree, --outline, --debug, or --deep for a more specific inspection mode
  • flash resources <project-id> to inspect reusable project and library resources
  • flash refresh-context <project-id> to regenerate local project context docs
  • flash context-check to see whether your local context is stale

Use --selector-path or --selector-key with inspect to target a single widget directly:

flash inspect <project-id> --page HomePage --selector-path "HomePage.body[0].children[1]" --dsl-json

When a Flash Selector v1 block is available (copied from the FlutterFlow editor's widget-tree right-click menu), use it to skip broad discovery and target the exact widget.

Recommended rule for existing apps: inspect first, then make changes.

If flutterflow CLI is installed, flash init --project <project-id> also exports a local generated-code snapshot into generated_code/ using the same project ID, API token, and base URL configuration.

After later flash run pushes, Flash marks that snapshot as stale instead of auto-refreshing it. Check freshness with flash codegen status and refresh on demand with flash codegen refresh.

CLI Workflow

The commands most developers use are:

flash init <name> [--project <id>]
flash doctor
flash --version
flash precache
flash validate <file> [--project-name <name> | --project-id <id>]
flash run <file> [--project-name <name> | --project-id <id>]
flash inspect <project-id> [--page <name> | --component <name>]
flash resources <project-id>
flash refresh-context <project-id>
flash context-check
flash codegen status
flash codegen refresh [--project-id <id>]
flash history
flash trace latest
flash support inspect <run-id>

flash validate is a dry run. It compiles and validates the DSL program without pushing changes to FlutterFlow.

flash doctor shows the installed Flash version, the current proto fingerprint, and whether the matching local validator binary is already cached for your platform.

flash --version prints the CLI/package version directly when you only need the release number.

flash precache downloads that validator ahead of time, so later flash validate and flash run calls can use the local validator immediately instead of fetching it on first use.

Agent-Friendly By Design

Flash works well for direct human use, but its workspace model is especially useful when you want agents involved in the workflow.

After flash init, the generated workspace already includes:

  • instructions in AGENTS.md and CLAUDE.md
  • reference DSL apps in references/
  • common existing-app patterns in patterns/
  • wrapper scripts in tooling/
  • local run history and traces in .flash/
  • generated-code freshness state and export manifest metadata under .flash/

Typical agent handoff:

  1. Run flash init ...
  2. Add FF_API_KEY to .env
  3. Ask the agent to read AGENTS.md
  4. Have it edit flash/app.dart or flash/brownfield_patch.dart
  5. Require flash validate before flash run
  6. If it uses generated_code/, require flash codegen status and flash codegen refresh when that snapshot is stale

For the lower-level helper and widget/action catalog, run flash docs api-surface or flash docs ui.

Learn By Reference

Start with the closest working example instead of writing a DSL from scratch.

  • shopflow_dsl.dart
  • taskboard_dsl.dart
  • auth_shell_dsl.dart
  • supabase_crud_auth_shell_dsl.dart
  • social_feed_data_dsl.dart
  • workflow_forms_dsl.dart
  • commerce_shell_dsl.dart
  • content_companion_dsl.dart
  • resource_library_dsl.dart
  • postgres_compile_only_dsl.dart
  • action_block_showcase_dsl.dart
  • app_event_showcase_dsl.dart
  • genui_catalog_assistant_dsl.dart
  • local_state_crud_dsl.dart
  • styled_profile_dsl.dart
  • media_browser_dsl.dart
  • asset_and_reference_surface_dsl.dart
  • brownfield_add_search_filter_dsl.dart
  • brownfield_form_and_detail_dsl.dart
  • brownfield_restyle_and_enhance_dsl.dart
  • multi_api_call_dsl.dart

All of these live under specs/dsl/.

More Docs

Read the package docs directly:

Or use the built-in docs commands:

  • flash docs readme
  • flash docs concepts
  • flash docs cli
  • flash docs mcp
  • flash docs troubleshooting
  • flash docs agent-setup
  • flash docs api-surface