Flutter architecture!!!

Flutter framework is open source, and has a thriving ecosystem of third-party packages that supplement the core library functionality.
This overview is divided into a number of sections:
- The layer model: The pieces from which Flutter is constructed.
- Reactive user interfaces: A core concept for Flutter user interface development.
- An introduction to widgets: The fundamental building blocks of Flutter user interfaces.
- The rendering process: How Flutter turns UI code into pixels.
- An overview of the platform embedders: The code that lets mobile and desktop OSes execute Flutter apps.
- Integrating Flutter with other code: Information about different techniques available to Flutter apps.
- Support for the web: Concluding remarks about the characteristics of Flutter in a browser environment.
Architectural layers
Flutter is designed as an extensible, layered system. It exists as a series of independent libraries that each depend on the underlying layer. No layer has privileged access to the layer below, and every part of the framework level is designed to be optional and replaceable.

Typically, developers interact with Flutter through the Flutter framework, which provides a modern, reactive framework written in the Dart language. It includes a rich set of platform, layout, and foundational libraries, composed of a series of layers. Working from the bottom to the top, we have:
- Basic foundational classes, and building block services such as animation, painting, and gestures that offer commonly used abstractions over the underlying foundation.
- The rendering layer provides an abstraction for dealing with layout. With this layer, you can build a tree of render able objects.
- The widgets layer is a composition abstraction. Each render object in the rendering layer has a corresponding class in the widgets layer.
- The Material and Cupertino libraries offer comprehensive sets of controls that use the widget layer’s composition primitives to implement the Material or iOS design languages.
Reactive user interfaces
In most traditional UI frameworks, the user interface’s initial state is described once and then separately updated by user code at runtime, in response to events. One challenge of this approach is that, as the application grows in complexity, the developer needs to be aware of how state changes cascade throughout the entire UI.
Widgets
Widgets form a hierarchy based on composition. Each widget nests inside its parent and can receive context from the parent. This structure carries all the way up to the root widget (the container that hosts the Flutter app, typically MaterialApp
or CupertinoApp
)
Composition
Widgets are typically composed of many other small, single-purpose widgets that combine to produce powerful effects.
Where possible, the number of design concepts is kept to a minimum while allowing the total vocabulary to be large. For example, in the widgets layer, Flutter uses the same core concept (a Widget
) to represent drawing to the screen, layout (positioning and sizing), user interactivity, state management, theming, animations, and navigation. In the animation layer, a pair of concepts, Animation
s and Tween
s, cover most of the design space.
Building widgets
As mentioned earlier, you determine the visual representation of a widget by overriding the build()
function to return a new element tree. This tree represents the widget’s part of the user interface in more concrete terms. For example, a toolbar widget might have a build function that returns a horizontal layout of some text and various buttons.
Widget state
The framework introduces two major classes of widget: stateful and stateless widgets.
Many widgets have no mutable state: they don’t have any properties that change over time (for example, an icon or a label). These widgets subclass StatelessWidget
.
However, if the unique characteristics of a widget need to change based on user interaction or other factors, that widget is stateful. For example, if a widget has a counter that increments whenever the user taps a button, then the value of the counter is the state for that widget. When that value changes, the widget needs to be rebuilt to update its part of the UI. These widgets subclass StatefulWidget
, and (because the widget itself is immutable) they store mutable state in a separate class that subclasses State
. StatefulWidget
s don’t have a build method; instead, their user interface is built through their State
object.
Whenever you mutate a State
object (for example, by incrementing the counter), you must call setState()
to signal the framework to update the user interface by calling the State
’s build method again.
State management
As with any other class, you can use a constructor in a widget to initialize its data, so a build()
method can ensure that any child widget is instantiated with the data it
As widget trees get deeper, however, passing state information up and down the tree hierarchy becomes cumbersome. So, a third widget type, InheritedWidget
, provides an easy way to grab data from a shared ancestor. You can use InheritedWidget
to create a state widget that wraps a common ancestor in the widget tree.
Rendering and layout
Flutter’s rendering model
Cross-platform frameworks typically work by creating an abstraction layer over the underlying native Android and iOS UI libraries, attempting to smooth out the inconsistencies of each platform representation. App code is often written in an interpreted language like JavaScript, which must in turn interact with the Java-based Android or Objective-C-based iOS system libraries to display UI. All this adds overhead that can be significant, particularly where there is a lot of interaction between the UI and the app logic.
From user input to the GPU
The overriding principle that Flutter applies to its rendering pipeline is that simple is fast. Flutter has a straightforward pipeline for how data flows to the system, as shown in the following sequencing diagram:


During the build phase, Flutter translates the widgets expressed in code into a corresponding element tree, with one element for every widget. Each element represents a specific instance of a widget in a given location of the tree hierarchy. There are two basic types of elements:
ComponentElement
, a host for other elements.RenderObjectElement
, an element that participates in the layout or paint phases.

RenderObjectElement
s are an intermediary between their widget analog and the underlying RenderObject
, which we’ll come to later.
The element for any widget can be referenced through its BuildContext
, which is a handle to the location of a widget in the tree. This is the context
in a function call such as Theme.of(context)
, and is supplied to the build()
method as a parameter.
Layout and rendering.
The base class for every node in the render tree is RenderObject
, which defines an abstract model for layout and painting. This is extremely general: it does not commit to a fixed number of dimensions or even a Cartesian coordinate system . Each RenderObject
knows its parent, but knows little about its children other than how to visit them and their constraints. This provides RenderObject
with sufficient abstraction to be able to handle a variety of use cases.
During the build phase, Flutter creates or updates an object that inherits from RenderObject
for each RenderObjectElement
in the element tree. RenderObject
s are primitives: RenderParagraph
renders text, RenderImage
renders an image, and RenderTransform
applies a transformation before painting its child.

Most Flutter widgets are rendered by an object that inherits from the RenderBox
subclass, which represents a RenderObject
of fixed size in a 2D Cartesian space. RenderBox
provides the basis of a box constraint model, establishing a minimum and maximum width and height for each widget to be rendered.
To perform layout, Flutter walks the render tree in a depth-first traversal and passes down size constraints from parent to child. In determining its size, the child must respect the constraints given to it by its parent. Children respond by passing up a size to their parent object within the constraints the parent established.

Platform embedding
The mechanism for obtaining the texture and participating in the app lifecycle of the underlying operating system inevitably varies depending on the unique concerns of that platform. The engine is platform-agnostic, presenting a stable ABI (Application Binary Interface) that provides a platform embedder with a way to set up and use Flutter.
Each platform has its own set of APIs and constraints. Some brief platform-specific notes:
- On iOS and macOS, Flutter is loaded into the embedder as a
UIViewController
orNSViewController
, respectively. The platform embedder creates aFlutterEngine
, which serves as a host to the Dart VM and your Flutter runtime, and aFlutterViewController
, which attaches to theFlutterEngine
to pass UIKit or Cocoa input events into Flutter and to display frames rendered by theFlutterEngine
using Metal or OpenGL. - On Android, Flutter is, by default, loaded into the embedder as an
Activity
. The view is controlled by aFlutterView
, which renders Flutter content either as a view or a texture, depending on the composition and z-ordering requirements of the Flutter content.
Integrating with other code
Flutter provides a variety of interoperability mechanisms, whether you’re accessing code or APIs written in a language like Kotlin or Swift, calling a native C-based API, embedding native controls in a Flutter app, or embedding Flutter in an existing application.
Platform channels
For mobile and desktop apps, Flutter allows you to call into custom code through a platform channel, which is a simple mechanism for communicating between your Dart code and the platform-specific code of your host app. By creating a common channel (encapsulating a name and a codec), you can send and receive messages between Dart and a platform component written in a language like Kotlin or Swift. Data is serialized from a Dart type like Map
into a standard format, and then deserialized into an equivalent representation in Kotlin (such as HashMap
) or Swift (such as Dictionary
).

Rendering native controls in a Flutter app
Flutter solves this by introducing platform view widgets (AndroidView
and UiKitView
) that let you embed this kind of content on each platform. Platform views can be integrated with other Flutter content4. Each of these widgets acts as an intermediary to the underlying operating system. For example, on Android,AndroidView
serves three primary functions:
- Making a copy of the graphics texture rendered by the native view and presenting it to Flutter for composition as part of a Flutter-rendered surface each time the frame is painted.
- Responding to hit testing and input gestures, and translating those into the equivalent native input.
- Creating an analog of the accessibility tree, and passing commands and responses between the native and Flutter layers.
Hosting Flutter content in a parent app
The converse of the preceding scenario is embedding a Flutter widget in an existing Android or iOS app. As described in an earlier section, a newly created Flutter app running on a mobile device is hosted in an Android activity or iOS UIViewController
. Flutter content can be embedded into an existing Android or iOS app using the same embedding API.
Flutter web support
On the web, Flutter provides a reimplementation of the engine on top of standard browser APIs. We currently have two options for rendering Flutter content on the web: HTML and WebGL. In HTML mode, Flutter uses HTML, CSS, Canvas, and SVG. To render to WebGL, Flutter uses a version of Skia compiled to WebAssembly called CanvasKit. While HTML mode offers the best code size characteristics, CanvasKit provides the fastest path to the browser’s graphics stack, and offers somewhat higher graphical fidelity with the native mobile targets5.
The web version of the architectural layer diagram is as follows:
