Flutter Widget Previewer: Visual Development Goes Mainstream
The Widget Previewer is now stable in Flutter 3.47. Learn how to use @Preview annotations to see widgets rendered in real-time without running your full app.
Published on • September 15, 2026
AI Assistant

The Widget Previewer reaches stable in Flutter 3.47, fundamentally changing how you develop widgets. Instead of running your entire app to see a single widget, you annotate it with @Preview and see it rendered instantly in your IDE.
What is the Widget Previewer?
The Widget Previewer is a development tool that renders individual widgets in isolation. You add a simple annotation, and your IDE shows a live preview of that widget — no full app build required.
import 'package:flutterPreview/flutter_preview.dart';
@Preview(name: 'Primary Button')
class PrimaryButtonPreview extends PreviewWidget {
@override
Widget build(BuildContext context) {
return PrimaryButton(
label: 'Submit',
onPressed: () {},
);
}
}
Setting up Widget Previewer
Enable the Widget Previewer in your Flutter project:
# pubspec.yaml
dev_dependencies:
flutter_test: any
flutter_preview: ^1.0.0
# Install dependencies
flutter pub get
# Enable previewer in VS Code settings
# Settings → Extensions → Flutter → Widget Previewer: Enable
The @Preview annotation
The @Preview annotation is the entry point for widget previews:
@Preview(
name: 'Login Form',
device: PreviewDevice.iphone14,
theme: PreviewTheme.dark,
)
class LoginFormPreview extends PreviewWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: Scaffold(
body: LoginForm(),
),
);
}
}
Preview configurations
You can configure previews with different devices, themes, and text scales:
@Preview(name: 'Mobile Light', device: PreviewDevice.pixel7)
class MobileLightPreview extends PreviewWidget { ... }
@Preview(name: 'Tablet Dark', device: PreviewDevice.ipadPro, theme: PreviewTheme.dark)
class TabletDarkPreview extends PreviewWidget { ... }
@Preview(name: 'Large Text', textScale: 2.0)
class LargeTextPreview extends PreviewWidget { ... }
Multiple previews per file
A single file can contain multiple preview widgets:
@Preview(name: 'Default')
class ButtonDefault extends PreviewWidget { ... }
@Preview(name: 'Disabled')
class ButtonDisabled extends PreviewWidget { ... }
@Preview(name: 'Loading')
class ButtonLoading extends PreviewWidget { ... }
The previewer shows all three states in a grid, making visual regression testing trivial.
Hot restart per preview
Each preview has its own isolated hot restart. Changes to a widget rebuild only that preview, not the entire preview grid:
// Editing this widget only restarts its preview
@Preview(name: 'Card')
class CardPreview extends PreviewWidget {
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Text('Updated content'), // Hot restart affects only this preview
),
);
}
}
Light/dark mode toggle
The previewer includes a built-in light/dark mode toggle. Your previews automatically adapt to the current theme:
@Preview(name: 'Themed Widget')
class ThemedPreview extends PreviewWidget {
@override
Widget build(BuildContext context) {
// This widget responds to the previewer's theme toggle
return Container(
color: Theme.of(context).colorScheme.surface,
child: Text(
'Hello',
style: TextStyle(color: Theme.of(context).colorScheme.onSurface),
),
);
}
}
Search and filter
With many previews, the search and filter system becomes essential:
// Tag your previews for filtering
@Preview(name: 'Button', tags: ['form', 'primary'])
class ButtonPreview extends PreviewWidget { ... }
@Preview(name: 'Input', tags: ['form', 'text'])
class InputPreview extends PreviewWidget { ... }
@Preview(name: 'Card', tags: ['display'])
class CardPreview extends PreviewWidget { ... }
Filter by tags in the previewer panel to focus on specific widget categories.
IDE integration
The Widget Previewer integrates with VS Code and Android Studio:
// .vscode/settings.json
{
"flutter.widgetPreviewer": true,
"flutter.widgetPreviewer.device": "pixel7",
"flutter.widgetPreviewer.theme": "system"
}
The preview panel appears alongside your code editor, showing live updates as you type.
Command-line mode
For CI/CD pipelines or headless environments, use the command-line previewer:
# Generate preview images
flutter test --preview-output=previews/
# Run previews in headless mode
flutter run --preview --headless
This enables automated visual testing without a display server.
Preview vs. widget testing
The Widget Previewer complements, not replaces, widget testing:
| Aspect | Previewer | Widget Testing |
|---|---|---|
| Purpose | Visual development | Automated verification |
| Speed | Instant | Build + run |
| Isolation | Visual only | Full widget lifecycle |
| Assertions | Visual inspection | Programmatic checks |
Use the previewer during development, widget tests in CI/CD.
Real-world workflow
A typical workflow with the Widget Previewer:
- Design a new widget in code
- Add
@Previewannotation - See it render immediately in the previewer
- Iterate on styling and layout visually
- Add widget tests for behavior
- Ship with confidence
The Widget Previewer eliminates the “run the whole app to see one button” anti-pattern. It’s the visual feedback loop Flutter developers have been waiting for.