A Flutter widget is the fundamental building block of a Flutter application. Everything in Flutter is a widget: layout elements, UI controls, styling providers, and even app-level configuration providers. From simple text labels to complex views handling navigation flows, Flutter widgets describe what the UI should look like for a given state.
Understanding how Flutter widgets work is critical for building maintainable and performant applications. The widget-based architecture encourages composition, reuse, and clear separation of concerns. It also directly impacts rebuild behavior, performance, and how state is managed across the app.
Many common performance issues in Flutter apps come from misunderstanding widget rebuilds rather than from rendering itself.
Flutter widgets are immutable. When the application state changes, Flutter creates new widget instances. The framework updates the existing element tree by comparing the new widgets with the previous ones (using type and keys), and only updates or recreates the underlying render objects where necessary.
Widgets form a tree structure. Each widget can have child widgets, which allows Flutter to model complex UIs as a hierarchy of simple components.
Every visual element in a Flutter app is represented as a widget.
This includes:
Widgets define how UI components appear and behave within the application.
Custom widgets should be introduced whenever there is a clear architectural or performance benefit.
Encapsulating reusable UI in a widget:
This helps keep the codebase organized and easier to maintain.
Widgets are also useful when a UI component becomes complex.
For example, a form with:
Breaking such components into smaller, self-contained widgets improves:
Separating widgets also helps isolate rebuild scope so Flutter redraws only the parts of the interface that change.
Custom widgets can abstract platform-specific differences.
For example, if a layout behaves differently on mobile and desktop, those differences can be encapsulated inside a widget while exposing a unified API to the rest of the application.
Widgets can also manage:
This keeps the codebase cleaner and easier to understand.
Widget are the foundation of Flutter UI, but they are not always the best choice for every layout scenario.
Avoid using regular Flutter widgets when the UI requires complex scrolling behavior with fine-grained control over layout and performance.
Standard widgets such as:
ListViewColumn inside a scroll viewcan become limiting or inefficient in these situations.
For advanced scrollable layouts, such as:
it is usually better to use Sliver.
Sliver-based widgets are designed specifically for complex scroll behavior and provide better control over:
If your UI requirements go beyond simple scrolling, it is worth learning how slivers work and when they are the right tool for the job.
Let's talk about tests! Dart and Flutter support three types of tests: Unit, Widget, and Integration tests. We'll start with a high-level overview of these different types of tests and when they're useful. Then, we'll dive into the details. See Brian Egan's presentation and become a pro in this topic.
7 min. • Dec 9, 2024
At LeanCode, while working on complex Flutter projects, we noticed that integrating widgets into Widgetbook was often repetitive and time-consuming. To address this, we created the Widgetbook Entries Generator - a VSCode extension that simplifies the process. See how it works.
12 min • Jul 27, 2023
Read about the LeanCode approach to Flutter architecture. We highlight some of the design decisions that should be made when developing a feature in mobile apps. This includes our approach to dependency injection, state management, widget lifecycle, and data fetching.