[
{
"No": "1",
"Category": "Widgets",
"Guideline": "Use StatelessWidget when possible",
"Description": "Immutable widgets are simpler",
"Do": "StatelessWidget for static UI",
"Don't": "StatefulWidget for everything",
"Code Good": "class MyWidget extends StatelessWidget",
"Code Bad": "class MyWidget extends StatefulWidget (static)",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html"
},
{
"No": "2",
"Category": "Widgets",
"Guideline": "Keep widgets small",
"Description": "Single responsibility principle",
"Do": "Extract widgets into smaller pieces",
"Don't": "Large build methods",
"Code Good": "Column(children: [Header() Content()])",
"Code Bad": "500+ line build method",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "3",
"Category": "Widgets",
"Guideline": "Use const constructors",
"Description": "Compile-time constants for performance",
"Do": "const MyWidget() when possible",
"Don't": "Non-const for static widgets",
"Code Good": "const Text('Hello')",
"Code Bad": "Text('Hello') for literals",
"Severity": "High",
"Docs URL": "https://dart.dev/guides/language/language-tour#constant-constructors"
},
{
"No": "4",
"Category": "Widgets",
"Guideline": "Prefer composition over inheritance",
"Description": "Combine widgets using children",
"Do": "Compose widgets",
"Don't": "Extend widget classes",
"Code Good": "Container(child: MyContent())",
"Code Bad": "class MyContainer extends Container",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "5",
"Category": "State",
"Guideline": "Use setState correctly",
"Description": "Minimal state in StatefulWidget",
"Do": "setState for UI state changes",
"Don't": "setState for business logic",
"Code Good": "setState(() { _counter++; })",
"Code Bad": "Complex logic in setState",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/State/setState.html"
},
{
"No": "6",
"Category": "State",
"Guideline": "Avoid setState in build",
"Description": "Never call setState during build",
"Do": "setState in callbacks only",
"Don't": "setState in build method",
"Code Good": "onPressed: () => setState(() {})",
"Code Bad": "build() { setState(); }",
"Severity": "High",
"Docs URL": ""
},
{
"No": "7",
"Category": "State",
"Guideline": "Use state management for complex apps",
"Description": "Provider Riverpod BLoC",
"Do": "State management for shared state",
"Don't": "setState for global state",
"Code Good": "Provider.of<MyState>(context)",
"Code Bad": "Global setState calls",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "8",
"Category": "State",
"Guideline": "Prefer Riverpod or Provider",
"Description": "Recommended state solutions",
"Do": "Riverpod for new projects",
"Don't": "InheritedWidget manually",
"Code Good": "ref.watch(myProvider)",
"Code Bad": "Custom InheritedWidget",
"Severity": "Medium",
"Docs URL": "https://riverpod.dev/"
},
{
"No": "9",
"Category": "State",
"Guideline": "Dispose resources",
"Description": "Clean up controllers and subscriptions",
"Do": "dispose() for cleanup",
"Don't": "Memory leaks from subscriptions",
"Code Good": "@override void dispose() { controller.dispose(); }",
"Code Bad": "No dispose implementation",
"Severity": "High",
"Docs URL": ""
},
{
"No": "10",
"Category": "Layout",
"Guideline": "Use Column and Row",
"Description": "Basic layout widgets",
"Do": "Column Row for linear layouts",
"Don't": "Stack for simple layouts",
"Code Good": "Column(children: [Text(), Button()])",
"Code Bad": "Stack for vertical list",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/Column-class.html"
},
{
"No": "11",
"Category": "Layout",
"Guideline": "Use Expanded and Flexible",
"Description": "Control flex behavior",
"Do": "Expanded to fill space",
"Don't": "Fixed sizes in flex containers",
"Code Good": "Expanded(child: Container())",
"Code Bad": "Container(width: 200) in Row",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "12",
"Category": "Layout",
"Guideline": "Use SizedBox for spacing",
"Description": "Consistent spacing",
"Do": "SizedBox for gaps",
"Don't": "Container for spacing only",
"Code Good": "SizedBox(height: 16)",
"Code Bad": "Container(height: 16)",
"Severity": "Low",
"Docs URL": ""
},
{
"No": "13",
"Category": "Layout",
"Guideline": "Use LayoutBuilder for responsive",
"Description": "Respond to constraints",
"Do": "LayoutBuilder for adaptive layouts",
"Don't": "Fixed sizes for responsive",
"Code Good": "LayoutBuilder(builder: (context constraints) {})",
"Code Bad": "Container(width: 375)",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html"
},
{
"No": "14",
"Category": "Layout",
"Guideline": "Avoid deep nesting",
"Description": "Keep widget tree shallow",
"Do": "Extract deeply nested widgets",
"Don't": "10+ levels of nesting",
"Code Good": "Extract widget to method or class",
"Code Bad": "Column(Row(Column(Row(...))))",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "15",
"Category": "Lists",
"Guideline": "Use ListView.builder",
"Description": "Lazy list building",
"Do": "ListView.builder for long lists",
"Don't": "ListView with children for large lists",
"Code Good": "ListView.builder(itemCount: 100, itemBuilder: ...)",
"Code Bad": "ListView(children: items.map(...).toList())",
"Severity": "High",
"Docs URL": "https://api.flutter.dev/flutter/widgets/ListView-class.html"
},
{
"No": "16",
"Category": "Lists",
"Guideline": "Provide itemExtent when known",
"Description": "Skip measurement",
"Do": "itemExtent for fixed height items",
"Don't": "No itemExtent for uniform lists",
"Code Good": "ListView.builder(itemExtent: 50)",
"Code Bad": "ListView.builder without itemExtent",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "17",
"Category": "Lists",
"Guideline": "Use keys for stateful items",
"Description": "Preserve widget state",
"Do": "Key for stateful list items",
"Don't": "No key for dynamic lists",
"Code Good": "ListTile(key: ValueKey(item.id))",
"Code Bad": "ListTile without key",
"Severity": "High",
"Docs URL": ""
},
{
"No": "18",
"Category": "Lists",
"Guideline": "Use SliverList for custom scroll",
"Description": "Custom scroll effects",
"Do": "CustomScrollView with Slivers",
"Don't": "Nested ListViews",
"Code Good": "CustomScrollView(slivers: [SliverList()])",
"Code Bad": "ListView inside ListView",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/SliverList-class.html"
},
{
"No": "19",
"Category": "Navigation",
"Guideline": "Use Navigator 2.0 or GoRouter",
"Description": "Declarative routing",
"Do": "go_router for navigation",
"Don't": "Navigator.push for complex apps",
"Code Good": "GoRouter(routes: [...])",
"Code Bad": "Navigator.push everywhere",
"Severity": "Medium",
"Docs URL": "https://pub.dev/packages/go_router"
},
{
"No": "20",
"Category": "Navigation",
"Guideline": "Use named routes",
"Description": "Organized navigation",
"Do": "Named routes for clarity",
"Don't": "Anonymous routes",
"Code Good": "Navigator.pushNamed(context '/home')",
"Code Bad": "Navigator.push(context MaterialPageRoute())",
"Severity": "Low",
"Docs URL": ""
},
{
"No": "21",
"Category": "Navigation",
"Guideline": "Handle back button (PopScope)",
"Description": "Android back behavior and predictive back (Android 14+)",
"Do": "Use PopScope widget (WillPopScope is deprecated)",
"Don't": "Use WillPopScope",
"Code Good": "PopScope(canPop: false, onPopInvoked: (didPop) => ...)",
"Code Bad": "WillPopScope(onWillPop: ...)",
"Severity": "High",
"Docs URL": "https://api.flutter.dev/flutter/widgets/PopScope-class.html"
},
{
"No": "22",
"Category": "Navigation",
"Guideline": "Pass typed arguments",
"Description": "Type-safe route arguments",
"Do": "Typed route arguments",
"Don't": "Dynamic arguments",
"Code Good": "MyRoute(id: '123')",
"Code Bad": "arguments: {'id': '123'}",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "23",
"Category": "Async",
"Guideline": "Use FutureBuilder",
"Description": "Async UI building",
"Do": "FutureBuilder for async data",
"Don't": "setState for async",
"Code Good": "FutureBuilder(future: fetchData())",
"Code Bad": "fetchData().then((d) => setState())",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html"
},
{
"No": "24",
"Category": "Async",
"Guideline": "Use StreamBuilder",
"Description": "Stream UI building",
"Do": "StreamBuilder for streams",
"Don't": "Manual stream subscription",
"Code Good": "StreamBuilder(stream: myStream)",
"Code Bad": "stream.listen in initState",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html"
},
{
"No": "25",
"Category": "Async",
"Guideline": "Handle loading and error states",
"Description": "Complete async UI states",
"Do": "ConnectionState checks",
"Don't": "Only success state",
"Code Good": "if (snapshot.connectionState == ConnectionState.waiting)",
"Code Bad": "No loading indicator",
"Severity": "High",
"Docs URL": ""
},
{
"No": "26",
"Category": "Async",
"Guideline": "Cancel subscriptions",
"Description": "Clean up stream subscriptions",
"Do": "Cancel in dispose",
"Don't": "Memory leaks",
"Code Good": "subscription.cancel() in dispose",
"Code Bad": "No subscription cleanup",
"Severity": "High",
"Docs URL": ""
},
{
"No": "27",
"Category": "Theming",
"Guideline": "Use ThemeData",
"Description": "Consistent theming",
"Do": "ThemeData for app theme",
"Don't": "Hardcoded colors",
"Code Good": "Theme.of(context).primaryColor",
"Code Bad": "Color(0xFF123456) everywhere",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/material/ThemeData-class.html"
},
{
"No": "28",
"Category": "Theming",
"Guideline": "Use ColorScheme",
"Description": "Material 3 color system",
"Do": "ColorScheme for colors",
"Don't": "Individual color properties",
"Code Good": "colorScheme: ColorScheme.fromSeed()",
"Code Bad": "primaryColor: Colors.blue",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "29",
"Category": "Theming",
"Guideline": "Access theme via context",
"Description": "Dynamic theme access",
"Do": "Theme.of(context)",
"Don't": "Static theme reference",
"Code Good": "Theme.of(context).textTheme.bodyLarge",
"Code Bad": "TextStyle(fontSize: 16)",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "30",
"Category": "Theming",
"Guideline": "Support dark mode",
"Description": "Respect system theme",
"Do": "darkTheme in MaterialApp",
"Don't": "Light theme only",
"Code Good": "MaterialApp(theme: light, darkTheme: dark)",
"Code Bad": "MaterialApp(theme: light)",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "31",
"Category": "Animation",
"Guideline": "Use implicit animations",
"Description": "Simple animations",
"Do": "AnimatedContainer AnimatedOpacity",
"Don't": "Explicit for simple transitions",
"Code Good": "AnimatedContainer(duration: Duration())",
"Code Bad": "AnimationController for fade",
"Severity": "Low",
"Docs URL": "https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html"
},
{
"No": "32",
"Category": "Animation",
"Guideline": "Use AnimationController for complex",
"Description": "Fine-grained control",
"Do": "AnimationController with Ticker",
"Don't": "Implicit for complex sequences",
"Code Good": "AnimationController(vsync: this)",
"Code Bad": "AnimatedContainer for staggered",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "33",
"Category": "Animation",
"Guideline": "Dispose AnimationControllers",
"Description": "Clean up animation resources",
"Do": "dispose() for controllers",
"Don't": "Memory leaks",
"Code Good": "controller.dispose() in dispose",
"Code Bad": "No controller disposal",
"Severity": "High",
"Docs URL": ""
},
{
"No": "34",
"Category": "Animation",
"Guideline": "Use Hero for transitions",
"Description": "Shared element transitions",
"Do": "Hero for navigation animations",
"Don't": "Manual shared element",
"Code Good": "Hero(tag: 'image' child: Image())",
"Code Bad": "Custom shared element animation",
"Severity": "Low",
"Docs URL": "https://api.flutter.dev/flutter/widgets/Hero-class.html"
},
{
"No": "35",
"Category": "Forms",
"Guideline": "Use Form widget",
"Description": "Form validation",
"Do": "Form with GlobalKey",
"Don't": "Individual validation",
"Code Good": "Form(key: _formKey child: ...)",
"Code Bad": "TextField without Form",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/Form-class.html"
},
{
"No": "36",
"Category": "Forms",
"Guideline": "Use TextEditingController",
"Description": "Control text input",
"Do": "Controller for text fields",
"Don't": "onChanged for all text",
"Code Good": "final controller = TextEditingController()",
"Code Bad": "onChanged: (v) => setState()",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "37",
"Category": "Forms",
"Guideline": "Validate on submit",
"Description": "Form validation flow",
"Do": "_formKey.currentState!.validate()",
"Don't": "Skip validation",
"Code Good": "if (_formKey.currentState!.validate())",
"Code Bad": "Submit without validation",
"Severity": "High",
"Docs URL": ""
},
{
"No": "38",
"Category": "Forms",
"Guideline": "Dispose controllers",
"Description": "Clean up text controllers",
"Do": "dispose() for controllers",
"Don't": "Memory leaks",
"Code Good": "controller.dispose() in dispose",
"Code Bad": "No controller disposal",
"Severity": "High",
"Docs URL": ""
},
{
"No": "39",
"Category": "Performance",
"Guideline": "Use const widgets",
"Description": "Reduce rebuilds",
"Do": "const for static widgets",
"Don't": "No const for literals",
"Code Good": "const Icon(Icons.add)",
"Code Bad": "Icon(Icons.add)",
"Severity": "High",
"Docs URL": ""
},
{
"No": "40",
"Category": "Performance",
"Guideline": "Avoid rebuilding entire tree",
"Description": "Minimal rebuild scope",
"Do": "Isolate changing widgets",
"Don't": "setState on parent",
"Code Good": "Consumer only around changing widget",
"Code Bad": "setState on root widget",
"Severity": "High",
"Docs URL": ""
},
{
"No": "41",
"Category": "Performance",
"Guideline": "Use RepaintBoundary",
"Description": "Isolate repaints",
"Do": "RepaintBoundary for animations",
"Don't": "Full screen repaints",
"Code Good": "RepaintBoundary(child: AnimatedWidget())",
"Code Bad": "Animation without boundary",
"Severity": "Medium",
"Docs URL": "https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html"
},
{
"No": "42",
"Category": "Performance",
"Guideline": "Profile with DevTools",
"Description": "Measure before optimizing",
"Do": "Flutter DevTools profiling",
"Don't": "Guess at performance",
"Code Good": "DevTools performance tab",
"Code Bad": "Optimize without measuring",
"Severity": "Medium",
"Docs URL": "https://docs.flutter.dev/tools/devtools"
},
{
"No": "43",
"Category": "Accessibility",
"Guideline": "Use Semantics widget",
"Description": "Screen reader support",
"Do": "Semantics for accessibility",
"Don't": "Missing accessibility info",
"Code Good": "Semantics(label: 'Submit button')",
"Code Bad": "GestureDetector without semantics",
"Severity": "High",
"Docs URL": "https://api.flutter.dev/flutter/widgets/Semantics-class.html"
},
{
"No": "44",
"Category": "Accessibility",
"Guideline": "Support large fonts",
"Description": "MediaQuery text scaling",
"Do": "MediaQuery.textScaleFactor",
"Don't": "Fixed font sizes",
"Code Good": "style: Theme.of(context).textTheme",
"Code Bad": "TextStyle(fontSize: 14)",
"Severity": "High",
"Docs URL": ""
},
{
"No": "45",
"Category": "Accessibility",
"Guideline": "Test with screen readers",
"Description": "TalkBack and VoiceOver",
"Do": "Test accessibility regularly",
"Don't": "Skip accessibility testing",
"Code Good": "Regular TalkBack testing",
"Code Bad": "No screen reader testing",
"Severity": "High",
"Docs URL": ""
},
{
"No": "46",
"Category": "Testing",
"Guideline": "Use widget tests",
"Description": "Test widget behavior",
"Do": "WidgetTester for UI tests",
"Don't": "Unit tests only",
"Code Good": "testWidgets('...' (tester) async {})",
"Code Bad": "Only test() for UI",
"Severity": "Medium",
"Docs URL": "https://docs.flutter.dev/testing"
},
{
"No": "47",
"Category": "Testing",
"Guideline": "Use integration tests",
"Description": "Full app testing",
"Do": "integration_test package",
"Don't": "Manual testing only",
"Code Good": "IntegrationTestWidgetsFlutterBinding",
"Code Bad": "Manual E2E testing",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "48",
"Category": "Testing",
"Guideline": "Mock dependencies",
"Description": "Isolate tests",
"Do": "Mockito or mocktail",
"Don't": "Real dependencies in tests",
"Code Good": "when(mock.method()).thenReturn()",
"Code Bad": "Real API calls in tests",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "49",
"Category": "Platform",
"Guideline": "Use Platform checks",
"Description": "Platform-specific code",
"Do": "Platform.isIOS Platform.isAndroid",
"Don't": "Same code for all platforms",
"Code Good": "if (Platform.isIOS) {}",
"Code Bad": "Hardcoded iOS behavior",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "50",
"Category": "Platform",
"Guideline": "Use kIsWeb for web",
"Description": "Web platform detection",
"Do": "kIsWeb for web checks",
"Don't": "Platform for web",
"Code Good": "if (kIsWeb) {}",
"Code Bad": "Platform.isWeb (doesn't exist)",
"Severity": "Medium",
"Docs URL": ""
},
{
"No": "51",
"Category": "Packages",
"Guideline": "Use pub.dev packages",
"Description": "Community packages",
"Do": "Popular maintained packages",
"Don't": "Custom implementations",
"Code Good": "cached_network_image",
"Code Bad": "Custom image cache",
"Severity": "Medium",
"Docs URL": "https://pub.dev/"
},
{
"No": "52",
"Category": "Packages",
"Guideline": "Check package quality",
"Description": "Quality before adding",
"Do": "Pub points and popularity",
"Don't": "Any package without review",
"Code Good": "100+ pub points",
"Code Bad": "Unmaintained packages",
"Severity": "Medium",
"Docs URL": ""
}
]