Dart's concurrency model is unusual: single-threaded event loop by default, with explicit Isolates for true parallelism. No shared memory, no race conditions, no mutex locks. This guide covers everything from the simple compute() helper to long-lived Isolate workers, structured concurrency patterns, and Stream-based reactive flows.
The Mental Model: Isolates vs Threads
Concept Dart Isolates JavaScript Workers Java Threads
Memory sharing No — message passing only No Yes (with sync overhead)
Startup cost ~1-5ms ~1ms ~0.1ms
Communication SendPort/ReceivePort postMessage Shared memory
Good for CPU-heavy tasks Background compute I/O + CPU mix
Dart's lack of shared memory is a feature: it makes concurrent code dramatically safer by eliminating data races entirely.
compute() — The 80% Solution
For one-off heavy operations, compute() handles Isolate lifecycle automatically:
// Top-level or static function only — closures capture state and can't cross Isolate boundaries List < Product > _parseProductsSync (…