Short answer: Create a command-line app with dart create -t console app, run it with dart run and build a native binary with dart compile exe. Types are non-nullable unless marked ?; handle null with ??, ?. and if (x != null). Use final for values set once and const for compile-time constants. Dart 3 adds records, pattern matching and sealed classes; Dart 3.13 adds primary constructors. Asynchronous code uses Future, async/await and Stream.
The examples in this Dart cheat sheet were run with the Dart SDK 3.13.5 (stable) on Linux on 9 October 2026, and checked with dart analyze.
Table of Contents
The dart command
| Command | What it does |
|---|---|
dart create -t console app | New command-line project (bin/, lib/, test/, pubspec.yaml) |
dart run / dart run bin/app.dart --flag | Run the package or one file with arguments |
dart compile exe bin/app.dart -o app | Self-contained native binary for the current OS |
dart pub add http | Add a dependency to pubspec.yaml and fetch it |
dart pub get / dart pub upgrade | Fetch / upgrade dependencies |
dart analyze | Static analysis and lints |
dart format . | Format all Dart files |
dart fix --apply | Apply automated fixes, e.g. after an SDK upgrade |
dart test | Run tests in test/ (uses package:test) |
dart --version | Show the SDK version |
New language features are enabled by the lower bound of the SDK constraint in pubspec.yaml. For example, sdk: ^3.13.0 turns on primary constructors.
Variables, types and null safety
| Syntax | What it does | Example |
|---|---|---|
var | Inferred, reassignable | var name = 'web01'; |
final | Set once at run time | final port = 443; |
const | Compile-time constant | const maxUsers = 1_000; |
int, double, num, String, bool | Core types | double ratio = 0.75; |
'$name:$port' / '${a + b}' | String interpolation | |
'''...''' | Multi-line string | |
int? maybe; | Nullable type; defaults to null | |
maybe ?? 0 | Default when null | |
maybe ??= 5; | Assign only if null | |
nick?.length | Null-aware access; result is nullable | |
maybe! | Assert non-null; throws if it is null | |
late String lazy; | Non-nullable, initialised later (error if read first) | |
int.tryParse('8080') | Parse, or null on failure (int.parse throws) |
Control flow and functions
final msg = switch (code) { // switch expression
200 => 'ok',
301 || 302 => 'redirect',
>= 400 && < 500 => 'client error',
_ => 'other',
};
String greet(String name, {String city = 'Leeds', required bool formal}) =>
formal ? 'Good day $name from $city' : 'Hi $name';
int add(int a, [int b = 0]) => a + b; // optional positional parameter
greet('Ali', formal: true);
greet('Sam', city: 'York', formal: false);
| Syntax | What it does |
|---|---|
for (var i = 0; i < 3; i++) | Classic loop |
for (final n in list) | Loop over any Iterable |
while / do { } while | Loops |
{required String x} | Named parameter that callers must pass |
=> expr | Arrow body for a single expression |
(int x) => x * x | Anonymous function (closure) |
Collections
| Syntax | What it does |
|---|---|
final nums = [5, 3, 8]; | List<int>; add, sort(), length, first, contains |
nums.where((n) => n.isEven).toList() | Filter (lazy until toList()) |
nums.map((n) => n * n).toList() | Transform |
nums.fold(0, (a, b) => a + b) | Reduce to one value |
final ports = {'ssh': 22}; | Map<String, int>; ports['ssh'] returns int? |
ports.remove('ssh'), containsKey | Remove / test a key |
counts.update(w, (v) => v + 1, ifAbsent: () => 1) | Counting |
final tags = {'a', 'b'}; | Set<String> |
[...a, ...b] | Spread |
['-v', if (debug) '--debug', for (final t in tags) '#$t'] | Collection if and for |
['-v', ?extra] | Null-aware element: added only when extra is not null (Dart 3.8+) |
list..sort()..add(1) | Cascade: several calls on the same object |
Classes, enums and extensions
// Dart 3.13 primary constructor: fields declared in the header
class Server(final String name, var int port) {
String get address => '$name:$port';
}
class Host {
final String name;
final int port;
Host(this.name, {this.port = 22});
Host.web(String name) : this(name, port: 443); // named constructor
factory Host.fromJson(Map<String, dynamic> j) =>
Host(j['name'] as String, port: j['port'] as int);
}
enum Level {
low(1),
high(5);
const Level(this.weight);
final int weight;
bool get isHigh => weight > 3;
}
Level lv = .low; // Dart 3.10 dot shorthand: type is inferred
extension on String {
bool get isIp => RegExp(r'^\d{1,3}(\.\d{1,3}){3}$').hasMatch(this);
}
| Keyword | Meaning |
|---|---|
extends | Inherit from one class |
implements | Promise to provide another type’s interface |
with Logger | Mix in a mixin |
abstract interface class | Can only be implemented, not instantiated |
sealed class | All subtypes are in the same library, so switch can be exhaustive |
final class / base class | Restrict extending or implementing outside the library |
@override | Mark an overriding member |
Dart 3.13 also reserves final and var on ordinary parameters for primary constructors, so code such as void f(final int x) no longer compiles with sdk: ^3.13.0.
Records and pattern matching
(String, int) parseAddr(String s) {
final parts = s.split(':');
return (parts[0], int.parse(parts[1]));
}
final (host, port) = parseAddr('db1:5432'); // destructuring
final rec = (name: 'web', port: 80); // named record fields
print(rec.port);
sealed class Event {}
class Login extends Event { Login(this.user, this.ok); final String user; final bool ok; }
class Restart extends Event { Restart(this.service); final String service; }
class Quit extends Event {}
String describe(Event e) => switch (e) { // exhaustive: no default needed
Login(user: var u, ok: false) => 'failed login $u',
Login(:var user) => 'login $user',
Restart(:var service) => 'restart $service',
Quit() => 'quit',
};
final json = {'user': 'bob', 'roles': ['admin']};
if (json case {'user': String u, 'roles': [String first, ...]}) {
print('$u $first'); // bob admin
}
Errors and async code
class ConfigException implements Exception {
ConfigException(this.message);
final String message;
@override
String toString() => 'ConfigException: $message';
}
try {
parsePort('70000');
} on ConfigException catch (e) {
print(e);
} catch (e, st) { // anything else, with stack trace
print('$e\n$st');
} finally {
print('done');
}
Future<int> fetchStatus(String host) async {
await Future.delayed(const Duration(milliseconds: 10));
return host.length;
}
final results = await Future.wait([fetchStatus('a'), fetchStatus('bbb')]);
final v = await fetchStatus('db1').timeout(const Duration(seconds: 5));
| Syntax | What it does |
|---|---|
Future<T> + async / await | One value that arrives later |
Future.wait([...]) | Run several futures and wait for all |
.timeout(duration) | Throws TimeoutException if too slow |
Stream<T> + async* / yield | A sequence of values over time |
await for (final x in stream) | Consume a stream |
await Isolate.run(() => heavyWork()) | Run CPU-heavy work on another isolate (dart:isolate) |
rethrow | Re-throw inside a catch block, keeping the stack trace |
Files, processes and a log example
For server admins: a small dart:io tool that counts requests per client IP, compiled to a single binary with dart compile exe.
import 'dart:io';
Future<void> main(List<String> args) async {
final path = args.isNotEmpty ? args.first : '/var/log/nginx/access.log';
final file = File(path);
if (!await file.exists()) {
stderr.writeln('cannot read $path');
exit(1);
}
final hits = <String, int>{};
for (final line in await file.readAsLines()) {
final ip = line.split(' ').first;
hits.update(ip, (n) => n + 1, ifAbsent: () => 1);
}
final top = hits.entries.toList()..sort((a, b) => b.value.compareTo(a.value));
for (final e in top.take(10)) {
print('${e.value.toString().padLeft(7)} ${e.key}');
}
}
| Syntax | What it does |
|---|---|
File(p).readAsString() / writeAsString(s) | Whole file in or out (async; ...Sync versions exist) |
File(p).openRead() | Stream a large file instead of loading it |
Directory(p).list() | List a directory as a stream |
await Process.run('systemctl', ['is-active', 'nginx']) | Run a command; read exitCode and stdout |
Platform.environment['HOME'] | Environment variable |
jsonEncode(obj) / jsonDecode(text) | JSON from dart:convert; classes need a toJson() method |
Official documentation (checked 9 October 2026): Dart language tour · Dart: Patterns · Dart: Sound null safety · The dart command-line tool · Dart API reference · Dart changelog
Dart Cheat Sheet at a glance


Related guides: Kotlin Cheat Sheet: Syntax, Null Safety and Collections · Swift Cheat Sheet: Syntax, Optionals, Protocols and async · TypeScript Cheat Sheet: Types, Generics and tsconfig.
Reading a lot of our guides? Go ad-free with srvScripts Pro for $6 a month. It also pays for new guides. Cancel any time.