Dart
Dart is the language of Flutter — a typed, garbage-collected, object-oriented language from Google that compiles to native ARM/x64 machine code, JavaScript, and WebAssembly. If you write Flutter apps (and millions of developers do), you write Dart all day.
Dart's design brief was pragmatic: familiar enough that Java/TypeScript/Kotlin developers are productive in a week, with the specific features UI development needs — sound null safety, fast hot-reload development (JIT) and fast startup in production (AOT), and single-threaded-by-default concurrency that can't data-race your widget tree.
TL;DR
- Dart is statically typed with inference (
var name = "Alice"is aString) and soundly null safe —Stringcan never hold null;String?can, and the compiler forces you to handle it. - Everything is an object; classes, interfaces (implicit), mixins, and extension methods cover the OO toolbox.
- Async is front and center:
Future/async/awaitfor one-shot values,Streamfor sequences — the backbone of every Flutter app's I/O. - Isolates instead of threads: memory-isolated workers with message passing — no shared-state data races, by construction.
- Two compilation modes power the workflow: JIT in development (sub-second hot reload) and AOT for release (fast native startup).
- Beyond Flutter, Dart runs CLIs and servers, but Flutter is ~95% of real-world Dart.
Quick Example
Idiomatic Dart — null safety, classes, async, and collection literals:
Core Concepts
Sound Null Safety
Dart's flagship feature: nullability lives in the type system, and the guarantee is sound — if the type says non-null, the runtime value is never null, so the compiler can both prevent null crashes and optimize around them.
The discipline this enforces is why "null check operator used on a null value" (a misused !) is essentially the only null crash left in Flutter apps — and it always points at a ! you wrote.
Classes, Mixins, and Extensions
Modern Dart (3.x) added records ((double, double) point = (3, 4)), pattern matching with switch expressions, and sealed classes for exhaustive state modeling — the toolkit for representing UI state safely:
Futures, Streams, and Isolates
Dart is single-threaded with an event loop (like JavaScript):
CPU-heavy work would freeze the UI frame loop, so Dart offers isolates — separate memory heaps communicating by message:
No shared memory means no locks and no data races — the trade is message-copy overhead.
The Toolchain
Plus pub (package manager, pub.dev), a formatter with zero configuration debates (dart format), and a capable analyzer/linter out of the box.
Dart vs Its Neighbors
Coming from TypeScript, Dart feels like "TS with sound types and a real standard library"; from Kotlin or Swift, it feels immediately familiar. The honest assessment: nobody chooses Dart in isolation — they choose Flutter, and Dart turns out to be one of Flutter's quiet strengths.
Common Mistakes
Scattering ! to Silence the Compiler
Every ! is a latent crash. Prefer ?., ??, flow-analysis promotion (if (x != null)), or restructuring so the value is non-null by construction. A codebase's ! count is a decent proxy for its null-safety debt.
Blocking the Event Loop
A tight loop parsing 50 MB of JSON freezes every animation frame. Anything meaningfully CPU-bound belongs in Isolate.run (Flutter's compute wraps the same idea).
Forgetting to await
Calling an async function without await silently drops errors and races the result. Enable the unawaited_futures lint — it turns this whole bug class into an analyzer warning.
Mutable Widget-Adjacent State
final by default, const constructors wherever possible. In Flutter specifically, const widgets skip rebuilds entirely — free performance for the discipline of immutability.
FAQ
Is Dart worth learning without Flutter?
Realistically, learn it for Flutter — that's where the jobs, packages, and community are. Standalone Dart is a pleasant CLI/server language (and shines in shared code between your app and backend), but it's not displacing Go or TypeScript on servers.
How hard is Dart coming from JavaScript/TypeScript?
Days, not weeks. Syntax, async/await, and the event loop transfer directly; the additions (sound types, real integers, isolates, no undefined) mostly remove pain rather than add it.
What was Dart 3's big deal?
100% sound null safety became mandatory, plus records, pattern matching, sealed/exhaustive switches, and class modifiers — collectively moving Dart from "Java-flavored" to a modern multi-paradigm language. WasmGC compilation matured after, speeding Flutter web.
Does Dart have a package ecosystem?
Yes — pub.dev hosts tens of thousands of packages with scoring and null-safety badges. Flutter dominates the catalog, but HTTP, JSON codegen, testing, and server frameworks are all well covered.
Dart on the backend — viable?
Viable (Dart Frog, Serverpod, shelf), and attractive when a Flutter team wants one language end-to-end with shared models. For a backend chosen on its own merits, Go, TypeScript/Node, or Python have far deeper ecosystems.
Related Topics
- Flutter — The framework Dart exists to power
- Kotlin — The closest language cousin (Android side)
- TypeScript — The web's typed counterpart
- React Native — Flutter's main cross-platform rival
- Async JavaScript — The same event-loop model in JS
- Mobile State Management — Where sealed classes earn their keep