Dart is more than just "Flutter's language." It is a carefully designed language with a clear purpose: making it easy to write expressive, high-performance applications for any platform. Before diving into widgets and UI patterns, building a solid understanding of Dart itself pays dividends in every Flutter project you ever write.
What Is Dart?
Dart is a statically typed, compiled, object-oriented programming language developed by Google. It was designed specifically for building user interfaces, but has grown into a general-purpose language targeting mobile, web, server, and desktop.
Key characteristics:
- Statically typed — variable types are known at compile time, catching errors early
- Object-oriented — everything is an object, including numbers and functions
- Garbage collected — memory is managed automatically
- Async-first — built-in
Future,Stream,async, andawaitprimitives - C-like syntax — familiar to developers coming from Java, C#, or JavaScript
Getting Started
Install the SDK
Download Dart from the official site:
# macOS via Homebrew
brew tap dart-lang/dart
brew install dart
# Verify installation
dart --version
Online Editor
For quick experiments without installing anything, use DartPad at dartpad.dev — a browser-based Dart editor with instant execution.
Basic Syntax
Dart uses C-style syntax. Every Dart program starts from the main() function.
void main() {
var firstName = 'Amr';
String lastName = 'Tarek';
print(firstName + ' ' + lastName); // Amr Tarek
}
Comments
// Single-line comment
/*
Multi-line
comment
*/
/// Documentation comment (appears in generated docs)
/// [parameter] describes a parameter
The Dart Virtual Machine (Dart VM)
The Dart VM is the runtime that executes Dart programs. It operates in two phases:
Dart VM Execution
------------------
Source Code (.dart)
|
v
[Compile Time]
- Parse and type-check
- Optimize
- Early error detection
|
v
[Runtime]
- Execute compiled code
- Manage memory allocation
- Handle dynamic operations
- Process user interactions
At compile time, Dart code is checked and optimized, ensuring early detection of type errors, unused variables, and other issues.
At runtime, the Dart VM executes the compiled code, managing dynamic operations such as memory allocation and user interactions.
Dart Compilation: AOT and JIT
Dart uses two compilation strategies — one for development speed and one for production performance.
+------------------------+ +------------------------+
| JIT Compilation | | AOT Compilation |
| (Development) | | (Production) |
| | | |
| Compiles at runtime | | Compiles before run |
| Enables hot reload | | Faster app startup |
| Fast iteration cycle | | Optimized performance |
| Includes debug info | | Smaller runtime |
+------------------------+ +------------------------+
JIT (Just-In-Time)
JIT compiles Dart code to machine code as the program runs, just before each piece of code is executed. This makes the famous hot reload possible — you change your code, save the file, and the running app reflects the change in under a second without losing state.
JIT is used only during development.
AOT (Ahead-Of-Time)
AOT compiles all Dart code to native machine code before the app starts. The result is a self-contained binary that starts faster and runs more efficiently than JIT-compiled code.
AOT is used for all production builds — release APKs, iOS apps, and web builds.
Dart Garbage Collection
Dart uses automatic garbage collection to manage memory. You allocate objects and Dart frees them when they are no longer reachable — you never call free() or delete.
Dart uses a generational garbage collection strategy:
Generational GC
----------------
New Objects --> Young Generation (collected frequently)
|
| (objects that survive multiple collections)
v
Old Generation (collected less frequently)
- Young generation — short-lived objects (temporary variables, intermediate calculations). Collected frequently and cheaply.
- Old generation — long-lived objects (app state, cached data). Collected less often.
This strategy minimizes GC pauses by focusing collection effort on the objects most likely to be garbage.
Concurrency in Dart
Dart handles concurrency through two mechanisms: Isolates and async programming.
Isolates
An Isolate is an independent unit of execution with its own memory heap. Isolates do not share memory — they communicate exclusively through message passing.
Isolate Architecture
---------------------
Main Isolate Background Isolate
+-------------+ +-------------+
| UI thread | <--msgs--> | Worker |
| Event loop | | Heavy work |
+-------------+ +-------------+
Own heap Own heap
(no sharing) (no sharing)
This design eliminates race conditions and data corruption from shared-memory concurrency.
import 'dart:isolate';
void heavyComputation(SendPort sendPort) {
// Runs in a separate isolate
int result = 0;
for (int i = 0; i < 1000000; i++) result += i;
sendPort.send(result);
}
void main() async {
final receivePort = ReceivePort();
await Isolate.spawn(heavyComputation, receivePort.sendPort);
final result = await receivePort.first;
print('Result: $result');
}
Async Programming
For I/O-bound operations (network requests, file reads), Dart uses async/await on a single-threaded event loop — no need for separate threads or isolates.
Future<void> loadData() async {
print('Starting...');
final data = await fetchFromServer(); // Does not block the event loop
print('Data: $data');
}
Core Dart Libraries
| Library | Purpose |
|---|---|
| dart:core | Automatically imported — basic types, collections, print |
| dart:async | Future, Stream, Completer for async programming |
| dart:io | File I/O, HTTP server, network sockets |
| dart:convert | JSON and UTF-8 encoding/decoding |
| dart:math | Mathematical functions, constants, random numbers |
| dart:collection | Extended collection types (Queue, LinkedList, etc.) |
A Minimal Dart Program
void main() {
// Print to console
print('Hello, Dart!');
// Variables
String name = 'Amr';
int age = 30;
double height = 1.82;
bool isFlutterDev = true;
// String interpolation
print('$name is $age years old and ${height}m tall.');
print('Flutter developer: $isFlutterDev');
}
Why Dart?
| Feature | Benefit |
|---|---|
| Static typing | Catches errors at compile time, better IDE support |
| AOT compilation | Fast startup, smooth runtime, ideal for mobile |
| JIT + hot reload | Rapid iteration during development |
| Async-first design | Clean, readable asynchronous code |
| Single-threaded + Isolates | Safe concurrency without shared-memory bugs |
| Null safety | Eliminates null reference errors by design |
Dart is a language designed for the use cases Flutter developers face every day. Learning it deeply — not just enough to write widgets — unlocks the full power of the Flutter platform.