Skip to content

Everything Is a Widget

Flutter has a slogan: everything is a widget. Layout, padding, a button, the whole app — all widgets. But the deeper truth is what a widget is: an immutable description of a piece of UI at one moment. It is not the thing on screen; it is a recipe for it.

Because widgets are immutable and cheap, Flutter’s answer to “the UI changed” is radical: throw the widgets away and build new ones. You never mutate a widget. You describe the new state, Flutter rebuilds the description, and it efficiently updates only what actually differs.

LessonWhat you’ll learn
Widgets and the treeImmutable config, composition, and the three trees (widget / element / render)
Stateless vs statefulThe two base widgets, and why State is a separate object
build and BuildContextThe build method’s contract, and what BuildContext really is
KeysWhen Flutter needs a key to preserve state correctly

If Flutter rebuilt everything on screen every frame, it would be unusably slow. The trick is that widgets are only the cheap top layer:

flowchart TB
  w["Widget
immutable description
(rebuilt freely)"] --> e["Element
living instance
(persists, holds state)"]
  e --> r["RenderObject
layout and paint
(the expensive part)"]
Three layers: cheap widgets, persistent elements, real rendering

Rebuilding widgets is cheap. The element and render layers underneath persist and are only updated where the new widget differs from the old. That split — disposable descriptions on top of durable machinery — is the whole performance story, and the next lesson makes it concrete.

What is a widget, most precisely?
How does Flutter respond to a state change?
Why is rebuilding widgets cheap?