Let’s be honest, most code reviews feel like an obligation. At best, they are just a quick, low-effort approval. At worst, they are a discouraging deep dive into every variable name you picked. But a good Flutter code review is none of that.
What to look for in a Flutter Code Review
Architecture and State Management Patterns
- Consistency: Does the code follow the established architecture pattern (BLoC, Riverpod, Provider, etc)? If there is a deviation, is there a strong and documented reason for it?
- Responsibility: Are widgets used only to render the UI? Is business logic properly separated into blocs, controllers, or notifiers? Are services handling API calls? Each part should have a single clear responsibility.
- State Propagation: Is state being passed efficiently? Are we using the right tools (such as
Provider.of,ref.watch, orcontext.select) to avoid unnecessary rebuilds?
UI Responsiveness
- Responsiveness: Does the layout work across different screen sizes and orientations? Are widgets like
LayoutBuilder,FractionallySizedBox, or flexible layouts being used correctly? - Widget Tree Depth: Is the widget tree unnecessarily deep? Complex
buildmethods can be broken into smaller, more manageable widgets. - Use of
const: Is theconstkeyword being used whenever possible for widgets that never change? This is one of the easiest performance wins in Flutter.
Performance and Memory Usage
Laggy animations and high memory usage are silent killers of a good user experience.
- Asynchronous Operations: Are
Futures andStreams managed correctly? Are loading and error states handled in async UI flows? Isawaitbeing used ininitStatewithout proper care? - Expensive Operations: Are heavy computations happening inside the
buildmethod? They should be moved out and cached. - Memory Leaks: Are controllers, subscriptions (like
StreamSubscription), and other resources disposed of properly indispose()? This is a classic source of bugs.
Error Handling and Null Safety
- Graceful Failure: Does the app crash when an API call fails or does it show a user friendly error message? Are
try-catchblocks used appropriately? - Null Safety: Is the code truly null-safe or full of bang operators (
!)? Every!is a potential runtime crash. Question every single one.
Coverage and Testability
- Is there a test? Does the change include a corresponding unit, widget, or integration test?
- Relevant Tests: Do the tests validate business logic and UI behavior or only check that the code does not crash?
- Testability: Is the code easy to test? If not, that is usually a sign of tightly coupled components that should be refactored (for example using dependency injection).
Code Style, Readability, and Documentation
This is about being a good teammate. The next person who touches this code (which might be you in six months) will thank you.
- Clarity: Are variable and method names clear and unambiguous?
- Comments: Do comments explain the *why*, not the *what*? Good code should be self explanatory; comments should provide context that code alone cannot.
- Consistency: Does the code follow the project’s established style guide (for example Effective Dart)?
✅ Practical Flutter Code Review Checklist
Here is a quick checklist for Flutter code reviews.
Architecture and Organization
The PR follows the team’s architecture pattern (MVC, MVVM, Clean, BLoC, etc.)
Responsibilities are clearly separated (UI, business logic, data access)
Folders and files are organized consistently with the rest of the project
State and Navigation
Consistent state management (Provider, BLoC, Riverpod, MobX, etc.)
No heavy business logic inside widgets
Well structured navigation (named routes, go_router, auto_route, etc.)
Proper handling of back and navigation scenarios (pop, deep links, etc.)
UI/UX
Proper use of reusable widgets (components, atoms, molecules)
Responsive layout (relative sizes, MediaQuery, LayoutBuilder)
Respects the global theme (ThemeData, centralized colors and typography)
Loading, empty, and error states are well handled in the UI
Performance
Avoids unnecessary rebuilds (const, selectors, widget splitting)
ListViews and Grids use builders and, when needed, ListView.builder or CachedNetworkImage
No heavy operations running on the main isolate without need (use Isolates or compute when appropriate)
Removed prints, excessive logs, and dead code
Error Handling
Errors and exceptions are handled consistently (try catch, Either Result, etc.)
Clear user feedback in case of failure
No sensitive stacktrace leaks to the end user
Backend Integration
Well defined models and DTOs (fromJson toJson, null safety)
Input and output data validation
Timeouts, network errors, and offline states handled properly
Security
No sensitive data hardcoded (tokens, keys, private URLs)
Correct use of secure storage (flutter_secure_storage when needed)
Logs do not expose sensitive information
Tests and Quality
Unit and widget tests exist for critical logic
All tests are passing
Code follows dart format and the project’s lint rules
Comments and class method variable names are clear and descriptive