Flutter Architecture & Lifecycle
Understand how Flutter renders pixels on screen from Dart code to canvas.
Architecture Overview
Flutter uses a layered architecture that gives you complete control over every pixel on screen. Unlike other cross-platform frameworks that bridge to native platform widgets, Flutter does not use platform UI widgets at all. Instead, it draws every pixel directly using its own rendering engine.
This approach has a massive advantage: your UI looks identical across iOS, Android, web, and desktop. There are no platform-specific rendering quirks, no inconsistent widget behavior, and no dependency on platform updates. Flutter owns the entire rendering pipeline from Dart code to pixels on screen.
- Dart Framework: Your Dart code, widgets, and business logic
- Rendering Layer: Skia/Impeller renders 2D graphics to canvas
- Engine: C++ core that manages the Dart runtime, graphics, and platform channels
- Embedder: Platform-specific shell (Android, iOS, web, desktop)
The Flutter Engine
The Flutter engine is the foundation that makes everything work. Written in C++, it handles the heavy lifting — executing Dart code, rendering graphics, managing text layout, and communicating with the underlying platform. You don't interact with the engine directly, but understanding what it does helps you make better architectural decisions.
The engine provides:
- Dart Runtime: Executes your Dart code (AOT or JIT)
- Skia / Impeller: Graphics library that draws to the screen
- Text Rendering: Font shaping and text layout
- Platform Channels: Communication bridge to native code
- Accessibility: Screen reader and semantics support
Flutter's rendering pipeline is what sets it apart from cross-platform frameworks like React Native. Instead of bridging to native platform widgets, Flutter draws every pixel directly onto a canvas using its own rendering engine (Skia/Impeller).
| Stage | Description | Key Class |
|---|---|---|
| 1. Widget Tree | Declarative UI description | StatelessWidget, StatefulWidget |
| 2. Element Tree | Mutable lifecycle management | Element |
| 3. RenderObject | Layout and painting logic | RenderBox |
| 4. Layer Tree | Compositing for the GPU | Layer |
| 5. Pixels | Final output on screen | Skia / Impeller engine |
Rendering Pipeline
Flutter renders frames in three phases, aiming for 60fps (or 120fps on ProMotion displays):
| Phase | Description | Output |
|---|---|---|
| Build | Widget tree → Element tree | Declarative UI description |
| Layout | Element tree → RenderObject tree | Position and size calculations |
| Paint | RenderObject → Canvas | Actual pixels on screen |
// Every frame, Flutter follows this pipeline:
//
// 1. BUILD: Your widget tree is traversed
// Widget.build() → returns child widgets
//
// 2. LAYOUT: Constraints flow down, sizes flow up
// Parent says: "Be at most 400px wide"
// Child says: "I need 300px"
//
// 3. PAINT: Each RenderObject draws itself
// Skia/Impeller renders to the GPU
Framework Layers
The Flutter framework (the Dart side) is organized in clean layers, each building on the one below. This layered design means you can use high-level widgets for most tasks, but drop down to lower levels when you need fine-grained control over rendering, animation, or gesture handling.
The layers from top to bottom:
- Widgets: Composition primitives (Container, Row, Text, etc.)
- Rendering: Layout, painting, and hit testing logic
- Animation: Tween animations, physics simulations
- Painting: Low-level canvas drawing primitives
- Gestures: Pointer event handling and recognizers
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'dftacademy',
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const Scaffold(
body: Center(child: Text('Hello, Flutter!')),
),
);
}
}
Summary
- Flutter renders directly to canvas — no platform UI widgets
- The engine uses Skia/Impeller for GPU-accelerated rendering
- Every frame: Build → Layout → Paint in under 16ms
- The framework is layered: Widgets → Rendering → Animation → Painting