Most responsive code reaches for MediaQuery and the screen size — but a widget rarely owns the whole screen. LayoutBuilder hands you the exact BoxConstraints your widget has been given, so a card can lay itself out one way inside a narrow phone column and another way inside a wide tablet pane, without ever knowing how big the screen is. This guide covers how LayoutBuilder exposes constraints, building breakpoints from maxWidth, how it differs from MediaQuery, the infinite-constraint trap, and when to use each, with paste-ready code.

The Complete Flutter Guide: Build Android, iOS and Web apps
Go from scratch to building industry-standard apps with Riverpod, Firebase, animations, REST APIs, and more.
Enrol nowEvery snippet below is paste-ready against current stable Flutter. LayoutBuilder is the constraint-aware sibling of the layout widgets in the layout widgets guide — and understanding constraints is what makes it click.
We'll read the constraints, branch on maxWidth for a breakpoint, build an adaptive grid, compare against MediaQuery, and avoid the infinite-constraint crash.
If you'd rather watch adaptive layouts built across phone, tablet, and desktop, the channel covers responsive Flutter end to end.
Reading the constraints
LayoutBuilder takes a builder callback that receives the BuildContext and the BoxConstraints the parent passed down. The most useful field is maxWidth — the widest the widget is allowed to be in its current slot.
LayoutBuilder(
builder: (context, constraints) {
return Text('I can be up to '
'${constraints.maxWidth.toStringAsFixed(0)} px wide');
},
)
The key idea: this is the size of this widget's box, not the screen. Place the same LayoutBuilder inside a half-width pane and maxWidth is half the screen — which is exactly what makes component-level responsiveness possible.
A maxWidth breakpoint
The classic pattern is to switch layout once the available width crosses a threshold. Below the breakpoint you show a single column; above it, a two-column row.
LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth >= 600) {
return Row(
children: const [
Expanded(child: DetailsPanel()),
Expanded(child: SidebarPanel()),
],
);
}
return Column(
children: const [DetailsPanel(), SidebarPanel()],
);
},
)
Because the decision uses the widget's own constraints, this card behaves correctly whether it fills a phone screen or sits in a narrow column of a desktop dashboard — no manual screen-size maths required.

Adaptive UIs, built properly
The Complete Flutter Guide covers constraints, breakpoints, and responsive design from the ground up.
Enrol nowAn adaptive grid
Combine LayoutBuilder with a GridView to pick a column count from the available width — more columns as the panel grows wider.
LayoutBuilder(
builder: (context, constraints) {
final columns = (constraints.maxWidth / 200).floor().clamp(1, 4);
return GridView.count(
crossAxisCount: columns,
children: products.map(ProductCard.new).toList(),
);
},
)
Dividing the available width by a target tile size gives a natural, fluid column count. For grids specifically, SliverGridDelegateWithMaxCrossAxisExtent does the same job built in — but LayoutBuilder is the general tool when the branching is more than column counting.
LayoutBuilder vs MediaQuery
Both answer "how much space do I have?", but at different scopes. MediaQuery.of(context).size reports the whole screen or window — right for page-level decisions like the overall navigation shell. LayoutBuilder reports the constraints of the specific box the widget occupies — right when a single component should adapt to its slot.
A good rule: use MediaQuery to decide the page skeleton (see the responsive Flutter UI guide), and LayoutBuilder to make individual widgets inside that skeleton adapt to the room they're given.
The infinite-constraint trap
LayoutBuilder reports whatever the parent passes. If the parent imposes no horizontal bound — inside a horizontal ListView, or a Row without an Expanded — then maxWidth is double.infinity, and comparing it to a breakpoint silently picks the "wide" branch forever or throws.
LayoutBuilder(
builder: (context, constraints) {
if (!constraints.hasBoundedWidth) {
return const NarrowLayout(); // safe fallback
}
return constraints.maxWidth >= 600
? const WideLayout()
: const NarrowLayout();
},
)
Guard with constraints.hasBoundedWidth, or give the LayoutBuilder a bounded parent, before you branch on the number.
Common mistakes
- Using MediaQuery for component-level adaptivity. A widget rarely owns the full screen; use
LayoutBuilderfor its own slot. - Branching on an infinite maxWidth. Guard with
hasBoundedWidthor bound the parent. - Heavy work inside the builder. It runs during layout and on every constraint change; keep it light.
- Forgetting it rebuilds on resize and rotation. That's the point, but don't assume it runs only once.
- Reaching for LayoutBuilder when a Flexible would do. Often plain constraints widgets solve it without a builder.
Frequently asked questions
What is LayoutBuilder used for in Flutter?
It exposes the BoxConstraints from the parent so a widget can adapt to the space it's actually given, rather than to the whole screen.
What is the difference between LayoutBuilder and MediaQuery in Flutter?
MediaQuery reports the screen size for page-level breakpoints; LayoutBuilder reports the widget's own box for component-level adaptivity.
Why does LayoutBuilder say maxWidth is infinity in Flutter?
Its parent imposed no width bound — a horizontal ListView or unconstrained Row. Guard with hasBoundedWidth or give it a bounded parent.
Does LayoutBuilder hurt performance in Flutter?
It rebuilds the child on constraint changes, which is usually cheap. Keep the builder body light since it can run during layout.
Further reads
Keep going with the tutorials that pair with this guide:
- Flutter Development Guide 2026 — the full Flutter hub.
- Flutter Layout Widgets Guide — the constraints rule behind LayoutBuilder.
- Responsive Flutter UI — page-level breakpoints with MediaQuery.
- Flutter GridView Tutorial — pair LayoutBuilder with a grid for adaptive column counts.
- Flutter Expanded vs Flexible — bound a widget's width so LayoutBuilder works.
Sources: Flutter documentation — LayoutBuilder, BoxConstraints, MediaQuery, and the "Understanding constraints" guide (docs.flutter.dev). Verified against current stable Flutter.