---
description: This rule explains Flutter widget patterns and best practices for cross-platform mobile development.
globs: **/*.dart
alwaysApply: false
---
# Flutter rules
- Use StatelessWidget for UI components without internal state.
- Use StatefulWidget for components that need to maintain state:
```dart
class Counter extends StatefulWidget {
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
void _increment() {
setState(() { _count++; });
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(onPressed: _increment, child: Text('Increment')),
],
);
}
}
```
- Use state management solutions (Provider, Bloc, Riverpod) for complex apps.
- Organize code with proper folder structure (models, screens, widgets, services).
- Use named routes for navigation with Navigator.pushNamed().
- Use async/await for asynchronous operations with proper error handling.
- Use themes for consistent styling across the app.
The Flutter rule in Cursor offers guidance on Flutter widget patterns and best practices for cross-platform mobile development. It provides a structured approach to developing Flutter applications with recommendations for widget types, state management, code organization, and more.
The Flutter rule encapsulates essential Flutter development patterns and best practices to help you write cleaner, more maintainable code. It focuses on several key areas:
This rule serves as a quick reference for Flutter developers, ensuring consistency in development practices and helping to avoid common pitfalls.
The rule distinguishes between two fundamental widget types:
StatelessWidget: Used for UI components that don't need to maintain state internally. These are simpler and more performant for static UI elements.
StatefulWidget: Used when a widget needs to maintain its own state. The rule includes a practical example of a counter implementation that demonstrates proper state management with the setState()
method.
For more complex applications, the rule recommends using established state management solutions like:
These solutions help manage application state more effectively than basic StatefulWidget approaches when your app grows in complexity.
Proper folder structure is emphasized with recommendations to organize code into clear categories:
This organization improves maintainability and makes it easier for team members to navigate the codebase.
To leverage this Flutter rule in Cursor:
The rule is defined in the file flutter.mdc
in your project's .cursor/rules
directory.
This rule is configured with a glob pattern (**/*.dart
), which means it will automatically attach whenever you're working with Dart files in your Flutter project.
When the rule is active, the AI agent in Cursor will have context about Flutter best practices and can provide more relevant suggestions for your Flutter code.
If you need to manually invoke the rule, you can type @flutter
in the chat or Cmd-K interface.
The rule recommends using named routes with Navigator.pushNamed()
for screen navigation, which offers several advantages:
When working with asynchronous operations, proper error handling is essential:
Future<void> fetchData() async {
try {
final result = await apiService.getData();
// Process result
} catch (e) {
// Handle error appropriately
print('Error fetching data: $e');
}
}
Using Flutter's theming system helps maintain visual consistency throughout your app:
MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
textTheme: TextTheme(
headline1: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
bodyText1: TextStyle(fontSize: 16),
),
),
// Rest of your app
)
By following these Flutter best practices as outlined in the rule, you'll create more maintainable, performant, and consistent Flutter applications.