Flutter
Flutter is Google's UI toolkit for building cross-platform apps — iOS, Android, web, and desktop — from a single Dart codebase. Unlike approaches that wrap native components, Flutter draws every pixel itself with its own rendering engine, which gives it remarkably consistent UI across platforms and the freedom to build highly custom designs without fighting platform widgets.
The mental model is the widget tree: everything you see (and much you don't — layout, padding, gestures) is a widget, and the UI is rebuilt from your state. Internalize that, pick a state-management approach, and standardize it early — those two choices shape the whole codebase.
TL;DR
- Excellent for highly custom UI and shared codebases.
- The widget tree is the core abstraction — everything is a widget.
- UI is rebuilt from state (
buildruns on change). - Choose a state management approach and standardize early.
Quick Example
A widget rebuilds its UI from state when setState runs:
Core Concepts
- Widgets — everything is a widget: UI elements and layout (padding, rows, columns).
- Stateless vs Stateful — stateless widgets are immutable; stateful widgets hold mutable state and rebuild.
build— the method that (re)constructs the UI from current state; called on every change.- Async —
Futures andStreams for asynchronous work, withFutureBuilder/StreamBuilderto render results.
State Management
Flutter's built-in setState works for local widget state, but apps need a strategy for shared state:
- Provider / Riverpod — dependency injection + reactive state; Riverpod is the modern favorite.
- Bloc / Cubit — structured, event-driven state with clear separation.
- Simpler patterns for small apps.
💡 The specific choice matters less than consistency — pick one and apply it across the team. See Mobile State Management.
Platform Integration
- Platform channels — call native (Kotlin/Swift) APIs from Dart when Flutter doesn't cover something.
- Plugins — a large pub.dev ecosystem of ready-made integrations (camera, storage, notifications).
Best Practices
- Standardize state management early — refactoring it later is painful.
- Keep
buildmethods cheap — they run often; extract widgets and avoid heavy work insidebuild. - Use
constwidgets where possible to skip unnecessary rebuilds. - Prefer composition — small, focused widgets over deeply nested monoliths.
- Set up crash reporting and staged store rollouts before launch.
Common Mistakes
Expensive work inside build
Rebuilding the whole tree for a small change
FAQ
Flutter or React Native?
Both produce high-quality cross-platform apps. Flutter draws its own UI with a custom engine, giving extremely consistent, pixel-perfect, highly-custom interfaces and strong performance — at the cost of learning Dart. React Native uses JavaScript/React and renders to native components, which suits teams with React/web experience and a large JS ecosystem. Choose Flutter for custom UI consistency and performance; React Native for JS familiarity and ecosystem overlap with web.
Why does Flutter use its own rendering engine instead of native widgets?
Because rendering everything itself (via Skia/Impeller) gives Flutter complete control over every pixel, so the UI looks identical across platforms and you can build any custom design without being constrained by — or fighting — native widget sets. The tradeoff is that Flutter must reimplement platform look-and-feel (which it does well via Material/Cupertino widgets) and the engine adds to app size.
What state management should I choose?
For most modern apps, Riverpod is a strong default — type-safe, testable, and not tied to the widget tree. Bloc/Cubit suits teams wanting strict structure and event-driven flows. Provider is simpler and well-established. For small apps, setState plus a little InheritedWidget may be enough. The key is to pick one early and apply it consistently; mixing approaches creates confusion.
Do I need to learn Dart, and is that a barrier?
Yes, Flutter uses Dart — but it's an approachable, statically-typed language that feels familiar to anyone who knows Java, JavaScript, or C#. Most developers become productive quickly. Dart's features (sound null safety, async/await, strong tooling) are well-suited to UI work, and the learning curve is rarely the main obstacle — understanding the widget tree and state management usually takes more effort.
Related Topics
- React Native — The main alternative
- Mobile Development — The hub
- Mobile State Management — Managing app state
- Mobile Navigation — Routing patterns
- Swift · Kotlin for Android — Native alternatives