Everything here applies to programming in general, written in Dart. If you already know another language, this will get you up to speed with Dart syntax. If you are completely new, start here.
For the full language reference, see the official Dart documentation.
Variables
Every program needs to store data. Variables give that data a name so you can use it later. Dart has four core types.
String name = 'Mitch';
int age = 25;
double price = 9.99;
bool isActive = true;You don't always need to write the type. Dart can figure it out with var. Use final when a value should only be set once, and constwhen it's known before the app even runs.
var city = 'Toronto'; // type inferred as String
final id = 12345; // set once at runtime
const pi = 3.14159; // set at compile timeOperators
Operators let you do math, compare values, and combine conditions. You will use these constantly.
Arithmetic
10 + 3 // 13 add
10 - 3 // 7 subtract
10 * 3 // 30 multiply
10 / 3 // 3.33 divide
10 ~/ 3 // 3 integer divide
10 % 3 // 1 remainderComparison
These return true or false.
5 == 5 // true equal
5 != 3 // true not equal
5 > 3 // true greater than
5 < 3 // false less than
5 >= 5 // true greater or equal
5 <= 3 // false less or equalLogical
Combine multiple conditions together.
true && false // false AND (both must be true)
true || false // true OR (at least one true)
!true // false NOT (flip it)Assignment
Shorthand for updating a value.
int x = 10;
x += 5; // x = 15
x -= 3; // x = 12
x *= 2; // x = 24
x ~/= 4; // x = 6Null Safety
In Dart, variables cannot be null by default. This prevents a whole class of bugs. If a value might not exist, you mark it with ? and Dart will force you to handle that case.
String name = 'Mitch'; // cannot be null
String? nickname; // can be null
nickname ?? 'fallback' // use fallback if null
nickname?.length // safe access, returns null if null
nickname! // assert not null (throws if null)Prefer ?? and ?. over !. The bang operator (!) will crash your app if the value is actually null.
Conditionals
Your code needs to make decisions. Conditionals let you run different code depending on whether something is true or false.
if / else
if (age >= 18) {
print('Adult');
} else if (age >= 13) {
print('Teen');
} else {
print('Child');
}Ternary
A compact one-liner for simple conditions.
String status = age >= 18 ? 'Adult' : 'Minor';Switch
When you are checking one value against multiple options, switch is cleaner than chaining if/else.
switch (status) {
case 'active':
print('Active');
case 'inactive':
print('Inactive');
default:
print('Unknown');
}Loops
When you need to do something more than once, use a loop. There are three common patterns.
for
Best when you know exactly how many times to repeat.
for (int i = 0; i < 5; i++) {
print(i); // 0, 1, 2, 3, 4
}for-in
Best for going through a list of items.
List<String> names = ['Alice', 'Bob', 'Charlie'];
for (final name in names) {
print(name);
}while
Keeps going until a condition becomes false.
int count = 0;
while (count < 3) {
print(count);
count++;
}Functions
As your code grows, you will want to organize it into reusable pieces. A function takes input, does something, and optionally returns output.
int add(int a, int b) {
return a + b;
}
// Arrow syntax for single expressions
int multiply(int a, int b) => a * b;Dart also supports named parameters wrapped in {}. Add required to make them mandatory, or give them a default value.
void greet(String name, {String? title}) {
print('${title ?? ""} $name');
}
void log(String message, {int level = 0}) {
print('[$level] $message');
}
greet('Mitch', title: 'Mr.');
log('App started');Classes
A class is a blueprint for creating objects. It groups related data (properties) and behavior (methods) together. Almost everything in Dart is an object.
class User {
final String name;
final int age;
User({required this.name, required this.age});
String greet() => 'Hi, I am $name';
}
final user = User(name: 'Mitch', age: 25);
print(user.greet());You can extend a class to build on top of it. The child class inherits everything and can override specific behavior.
class Admin extends User {
final String role;
Admin({required super.name, required super.age, required this.role});
@override
String greet() => 'Hi, I am $name ($role)';
}Collections
Most apps work with groups of data. Dart gives you three built-in collection types.
List
Ordered and allows duplicates. This is the one you will use most.
List<String> fruits = ['apple', 'banana', 'cherry'];
fruits.add('date');
fruits.remove('banana');
String first = fruits[0];Map
Stores data as key-value pairs. Look up values by their key.
Map<String, int> scores = {
'math': 95,
'science': 88,
};
scores['english'] = 92;
int? mathScore = scores['math'];Set
Like a list, but every value must be unique.
Set<int> ids = {1, 2, 3};
ids.add(2); // ignored, already existsCommon Operations
These work on any collection.
fruits.where((f) => f.startsWith('a')); // filter
fruits.map((f) => f.toUpperCase()); // transform
fruits.contains('apple'); // check
fruits.length; // countEnums
An enum defines a fixed set of named values. Use them whenever a variable should only be one of a few specific options. You will see enums everywhere in Flutter (alignment, colors, status types).
enum Status { active, inactive, banned }
Status userStatus = Status.active;
if (userStatus == Status.active) {
print('User is active');
}
// Switch on all cases
switch (userStatus) {
case Status.active:
print('Active');
case Status.inactive:
print('Inactive');
case Status.banned:
print('Banned');
}Async / Await
Almost every app needs to wait for something. An API call, a database read, a timer. In Dart, these operations return a Future, which is a value that will arrive later.
Future<String> fetchUsername() async {
await Future.delayed(Duration(seconds: 2));
return 'Mitch';
}Mark the function async, then use await to pause until the result is ready. Always wrap await calls in try/catch for anything that can fail, like network requests.
void loadUser() async {
try {
final name = await fetchUsername();
print(name);
} catch (e) {
print('Error: $e');
}
}