Home
Dart
OOP
Flutter
Contact

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
ℹ️ Impeller Starting from Flutter 3.16, Impeller is the default rendering engine on iOS and Android, replacing Skia. It pre-compiles shaders to eliminate shader compilation jank.

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).

StageDescriptionKey Class
1. Widget TreeDeclarative UI descriptionStatelessWidget, StatefulWidget
2. Element TreeMutable lifecycle managementElement
3. RenderObjectLayout and painting logicRenderBox
4. Layer TreeCompositing for the GPULayer
5. PixelsFinal output on screenSkia / Impeller engine
📐 Why This Matters Because Flutter controls the entire rendering pipeline, your UI looks identical across iOS, Android, web, and desktop. There are no "platform-specific rendering quirks" — Flutter literally draws every pixel from scratch. This is also why Flutter can achieve 60fps animations consistently.

Rendering Pipeline

Flutter renders frames in three phases, aiming for 60fps (or 120fps on ProMotion displays):

PhaseDescriptionOutput
BuildWidget tree → Element treeDeclarative UI description
LayoutElement tree → RenderObject treePosition and size calculations
PaintRenderObject → CanvasActual pixels on screen
Flutter Build Context
// 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:

  1. Widgets: Composition primitives (Container, Row, Text, etc.)
  2. Rendering: Layout, painting, and hit testing logic
  3. Animation: Tween animations, physics simulations
  4. Painting: Low-level canvas drawing primitives
  5. Gestures: Pointer event handling and recognizers
minimal_app.dart
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
🚀 Next Step Continue to Stateless vs Stateful Widgets to learn about widget lifecycles.
K
Kesavaraja Murugesan
Flutter Developer & Educator

Flutter developer with 3 years of experience building production-grade mobile applications. Passionate about teaching clean architecture patterns and helping developers write maintainable, scalable code.

← Mixins & Extensions Next: Widgets →