Dart Internals, Version History and Effective Dart
50.1 How Dart Runs
Sound type system: runtime checks where needed (casts, covariant generics), plus AOT optimizations based on sound types (type-flow analysis, devirtualization, tree shaking).
Hot reload: the VM injects updated kernel code into the running isolate while preserving state (Flutter's signature feature).
Source (.dart) → Common Front End (CFE) → Kernel AST (.dill)
├── Dart VM: JIT (development, hot reload) / AOT compiler → native machine code (precompiled snapshot)
├── dart2js → optimized JavaScript (web production) / DDC → modular JS (web development)
└── dart2wasm → WebAssembly with WasmGC
Runtime: per-isolate heaps, generational GC (scavenger for the young generation, mark-sweep/compact for the old generation), event loop, isolate groups50.2 Version History Highlights
Initial stable release (optional typing, Dartium) Sound type system, strong mode, a focus on client/Flutter
Collection if/for/spread, extension methods Sound null safety (opt-in), FFI stable
Type aliases, constructor tear-offs, enhanced enums, super parameters, named args anywhere, Isolate.run
100% sound null safety, records, patterns, class modifiers (sealed/base/final/interface), switch expressions
Private final field promotion, Wasm progress Extension types, new JS interop (dart:js_interop)
Wasm compilation stable for Flutter web, macros preview (later cancelled), package:web 1.0 Digit separators, pub workspaces
Wildcard variables (_), the new "tall style" formatter Null-aware elements (?x in collection literals), cross-compilation for Linux, formatter improvements
Analyzer plugins, dot shorthands (3.10), native assets / build hooks, continued performance work (check the release notes for details)
50.3 Effective Dart: Key Guidelines
UpperCamelCase for types/extensions/enums, lowerCamelCase for members/variables/constants, lowercase_with_underscores for files/packages/import prefixes.
Use dart format. Prefer single quotes (per the lints). Use curly braces for all flow control (except single-line if without else).
✅ Use collection literals ([], {}), isEmpty/isNotEmpty, whereType, interpolation, ??/?., => for one-liners, initializing formals (this.x), and super parameters.
✅ Prefer final for locals/fields that don't change, and const where possible.
✅ Make classes immutable when practical. Override == and hashCode together.
✅ Use async/await over raw then chains. Always handle Future errors.
✅ Use sealed classes + switch for closed hierarchies, records for small aggregates, and extension types for type-safe wrappers.
❌ Avoid dynamic, late misuse, ! without justification, print in libraries (use logging), and catching without on clauses.
Name things clearly (verbs for side-effecting methods, nouns/adjectives for properties). Prefer named parameters for booleans and optional arguments.
Keep the public API small (lib/src for implementation, export a curated API). Use abstract interface class for contracts.
Design for testability: inject dependencies (clients, clocks, file systems).
Document every public API with ///. Start with a summary sentence. Use [references]. Include examples.