widget-previewer
Flutter Widget Previewer
Preview Flutter widgets in real-time, separate from a full app, in the Chrome browser.
Requirements
- Flutter version 3.35 or higher (for basic functionality)
- Flutter version 3.38 or higher (for IDE support)
- Chrome browser
Starting the Widget Previewer
From IDEs (Flutter 3.38+)
IDEs automatically start the Widget Previewer on launch:
Android Studio / IntelliJ: Open the "Flutter Widget Preview" tab in the sidebar
Visual Studio Code: Open the "Flutter Widget Preview" tab in the sidebar
From Command Line
flutter widget-preview start
This launches a local server and opens Chrome with the Widget Preview environment.
Basic Preview Usage
Import the preview package and use the @Preview annotation:
import 'package:flutter/widget_previews.dart';
import 'package:flutter/material.dart';
(name: 'My Sample Text')
Widget mySampleText() {
return const Text('Hello, World!');
}
Valid @Preview Targets
- Top-level functions returning
WidgetorWidgetBuilder - Static methods within a class returning
WidgetorWidgetBuilder - Public Widget constructors and factories with no required arguments
Preview Controls
Each preview instance provides controls (left to right):
- Zoom in: Magnify the widget
- Zoom out: Reduce magnification
- Reset zoom: Return to default zoom level
- Toggle light/dark mode: Switch theme
- Hot restart: Restart only this specific preview
For global state changes, use the hot restart button at the bottom right of the environment.
Customizing Previews
The @Preview annotation accepts these parameters:
| Parameter | Type | Description |
|---|---|---|
name |
String | Descriptive name for the preview |
group |
String | Group name to organize related previews |
size |
Size | Artificial size constraints |
textScaleFactor |
double | Custom font scale |
wrapper |
Function | Widget tree wrapper (e.g., for InheritedWidget state) |
theme |
Function | Material/Cupertino theming data provider |
brightness |
Brightness | Initial theme brightness |
localizations |
Function | Localization configuration |
Example with multiple parameters:
(
name: 'Button - Large',
group: 'Buttons',
size: Size(200, 100),
textScaleFactor: 1.5,
brightness: Brightness.dark,
)
Widget largeButton() => ElevatedButton(
onPressed: () {},
child: const Text('Large Button'),
);
Creating Custom Preview Annotations
Extend Preview to reduce boilerplate for common configurations:
final class MyCustomPreview extends Preview {
const MyCustomPreview({
super.name,
super.group,
super.size,
super.textScaleFactor,
super.wrapper,
super.brightness,
super.localizations,
}) : super(theme: MyCustomPreview.themeBuilder);
static PreviewThemeData themeBuilder() {
return PreviewThemeData(
materialLight: ThemeData.light(),
materialDark: ThemeData.dark(),
);
}
}
Runtime Transformations
Override transform() for runtime preview modifications:
final class TransformativePreview extends Preview {
const TransformativePreview({
super.name,
super.group,
super.size,
super.textScaleFactor,
super.wrapper,
super.brightness,
super.localizations,
});
PreviewThemeData _themeBuilder() {
return PreviewThemeData(
materialLight: ThemeData.light(),
materialDark: ThemeData.dark(),
);
}
Preview transform() {
final originalPreview = super.transform();
final builder = originalPreview.toBuilder();
builder
..name = 'Transformed - ${originalPreview.name}'
..theme = _themeBuilder;
return builder.toPreview();
}
}
Multiple Preview Configurations
Apply multiple @Preview annotations for different configurations:
(
group: 'Brightness',
name: 'Example - light',
brightness: Brightness.light,
)
(
group: 'Brightness',
name: 'Example - dark',
brightness: Brightness.dark,
)
Widget buttonPreview() => const ButtonShowcase();
MultiPreview for Batched Configurations
Extend MultiPreview to create custom multi-preview annotations:
final class MultiBrightnessPreview extends MultiPreview {
const MultiBrightnessPreview();
List<Preview> get previews => const [
Preview(
group: 'Brightness',
name: 'Example - light',
brightness: Brightness.light,
),
Preview(
group: 'Brightness',
name: 'Example - dark',
brightness: Brightness.dark,
),
];
}
()
Widget buttonPreview() => const ButtonShowcase();
MultiPreview with Runtime Transformations
final class MultiBrightnessPreview extends MultiPreview {
const MultiBrightnessPreview({required this.name});
final String name;
List<Preview> get previews => const [
Preview(brightness: Brightness.light),
Preview(brightness: Brightness.dark),
];
List<Preview> transform() {
final previews = super.transform();
return previews.map((preview) {
final builder = preview.toBuilder()
..group = 'Brightness'
..name = '$name - ${preview.brightness!.name}';
return builder.toPreview();
}).toList();
}
}
(name: 'Example')
Widget buttonPreview() => const ButtonShowcase();
IDE Integration
Filtering by Selected File
The widget previewer filters previews based on the currently selected file in your IDE. Toggle "Filter previews by selected file" at the bottom left to disable this behavior.
Restrictions and Limitations
Callback Requirements
All callback arguments must be public and constant for code generation to work.
Unsupported APIs
- Native plugins - Not supported (previewer uses Flutter Web)
dart:io- APIs will throw exceptions when invokeddart:ffi- Widgets will fail to load completely
Widgets with transitive dart:io dependencies load but throw on API calls. Widgets with transitive dart:ffi dependencies fail to load entirely.
Solution: Use conditional imports for platform-specific code:
import 'my_api_stub.dart'
if (dart.library.io) 'my_api_io.dart'
if (dart.library.html) 'my_api_web.dart';
Asset Paths
Use package-based paths for fromAsset APIs:
// Correct
'packages/my_package_name/assets/my_image.png'
// Incorrect
'assets/my_image.png'
Unconstrained Widgets
Automatically constrained to ~50% of previewer dimensions. Apply explicit size parameters for consistent behavior.
Multi-Project Support
Currently supports only single projects or Pub workspaces. Multi-project IDE sessions are not yet supported.
Troubleshooting
| Issue | Solution |
|---|---|
| Widget not appearing | Verify @Preview annotation is on valid target (top-level function, static method, or public constructor with no required args) |
| dart:io errors | Use conditional imports to provide web-compatible implementations |
| dart:ffi errors | Isolate ffi-dependent code and exclude from preview targets |
| Assets not loading | Use package-based asset paths |
| IDE not showing previewer | Ensure Flutter 3.38+ and check IDE plugin settings |
| Previews not updating | Try hot restart on individual preview or global hot restart |
References
- API Documentation
- Flutter Widget Previewer Guide - Complete documentation reference
More from ab22593k/skills
latency-principles
Comprehensive framework for diagnosing, optimizing, and hiding latency in software systems. You MUST use this skill whenever the user mentions slow performance, response time, p99/tail latency, or asks about system throughput and concurrency. It covers Little's Law, Amdahl's Law, and strategies for Data/Compute optimization (e.g., zero-copy, wait-free sync, request hedging). Trigger this even for theoretical questions about latency laws or ballpark estimations using latency constants.
14expressive-design
Material 3 Expressive design system for Flutter (Android & Linux). You MUST use this skill whenever the user asks to improve, modernize, or transform a Flutter UI, especially for consumer, media, or communication apps. It provides exact specs for Bento Grids, Masonry, color convergence, variable fonts, and expressive motion. Trigger this for any request involving 'modern' or 'emotionally engaging' Flutter widgets, even if they don't explicitly mention 'Expressive' design. Do NOT use for banking or safety-critical apps where standard M3 is required.
13generative-thinker
Guides the agent to apply Generativity Theory to solve problems by building high-leverage, open-ended systems. Use this skill when the user asks for "out of the box" ideas, platform strategies, or when a task benefits from enabling others to innovate rather than providing a narrow, single-purpose fix.
3effective-testing
A comprehensive methodology for highly effective, human-centered software testing, based on 'Taking Testing Seriously' (Bach & Bolton, 2026). Use this skill whenever testing, quality assurance, bug hunting, test strategy, automation traps, or risk analysis are mentioned. MANDATORY for: (1) Designing test strategies for complex products, (2) Performing exploratory testing using Session-Based Test Management (SBTM), (3) Identifying bugs with advanced oracle heuristics (FEW HICCUPS), (4) Reporting bugs with high business significance, (5) Prospective testing on requirements/designs, or (6) Supervizing AI and signals-based testing. If the user asks 'Is this code good?', 'How should I test this?', or 'Help me find bugs', YOU MUST use this skill to provide a professional, context-driven investigation rather than shallow checks.
2kernel-maintainer
YOU MUST use this skill for ANY Rust Linux kernel work. This includes: writing kernel modules in Rust, reviewing Rust kernel patches, debugging kernel panics/crashes, working with kernel APIs (Mutex, SpinLock, UserPtr, IOCTL), adding module parameters, creating device drivers (character/block/network), handling kernel errors, memory allocation in kernel, and following kernel Rust coding standards. If the user mentions 'kernel' and 'Rust' together, USE THIS SKILL. Essential for kernel maintainers, patch contributors, and developers working with Rust For Linux (RFL).
1latency principles
Comprehensive framework for diagnosing, optimizing, and hiding latency in software systems. You MUST use this skill whenever the user mentions slow performance, response time, p99/tail latency, or asks about system throughput and concurrency. It covers Little's Law, Amdahl's Law, and strategies for Data/Compute optimization (e.g., zero-copy, wait-free sync, request hedging). Trigger this even for theoretical questions about latency laws or ballpark estimations using latency constants.
1