dart-migration-versioning
Dart Version Management and Migration
Goal
Manages Dart language versioning, resolves breaking changes during SDK upgrades, and applies per-library version overrides to facilitate gradual migrations. Assumes a standard Dart or Flutter environment with access to pubspec.yaml and source files. Related Skills: dart-web-development, dart-static-analysis.
Decision Logic
When tasked with upgrading a Dart project or fixing version-related compilation errors, follow this evaluation path:
- Identify Target SDK: Determine the target Dart SDK version.
- Check Current Version: Read
pubspec.yamlto find the current lower bound SDK constraint. - Evaluate Breaking Changes: Cross-reference the version jump with the breaking changes log.
- If migrating to >= 3.0.0: Sound null safety is strictly enforced.
- If migrating web libraries to >= 3.3.0: Legacy
dart:htmlanddart:jsare deprecated/removed.
- Determine Migration Strategy:
- Can the code be refactored immediately? -> Apply API migrations.
- Is the refactor too large or blocked? -> Pin specific files using
@dart = <version>to maintain older language semantics while upgrading the package.
Instructions
-
Verify Current Language Version Requirements Inspect the
pubspec.yamlfile to determine the default language version, which is dictated by the lower bound of the SDK constraint.environment: sdk: '>=2.18.0 <3.0.0' # Defaults to Dart 2.18 -
Consult Breaking Change Logs Before performing major dependency or SDK upgrades, review the breaking changes for the target version. STOP AND ASK THE USER: "I am about to upgrade the SDK constraint to
<target_version>. This includes breaking changes such as<list_key_changes>. Should I proceed with the upgrade and begin refactoring?" -
Apply Per-Library Language Version Selection (Gradual Migration) If a specific file cannot be immediately migrated to the new language version (e.g., pending null safety migration or complex refactoring), pin the file to an older version.
- The
@dartstring must be in a//comment. - It must appear before any Dart code in the file.
// @dart = 2.19 import 'dart:math'; // Legacy code that relies on 2.19 semantics void legacyFunction() { // ... } - The
-
Migrate Deprecated Web and JS Interop Libraries (Dart 3.3+) If the project targets Dart 3.3+ or compiles to Wasm, legacy web libraries (
dart:html,dart:js,package:js) will cause compilation errors. Migrate these topackage:webanddart:js_interop.// BEFORE (Legacy) import 'dart:html'; import 'package:js/js.dart'; () external void legacyJsFunction(); // AFTER (Modern) import 'package:web/web.dart' as web; import 'dart:js_interop'; () external void modernJsFunction(); void updateDom() { final div = web.document.createElement('div') as web.HTMLDivElement; div.text = 'Migrated'; web.document.body?.append(div); } -
Validate-and-Fix Loop After updating the SDK constraint or modifying code, run static analysis to verify the migration.
dart analyzeFixing common post-upgrade errors:
- If
unnecessary_non_null_assertionorinvalid_null_aware_operatorappears, remove the!or?.as type promotion has likely improved in the newer Dart version. - If
dart:js_utilordart:htmlthrows Wasm compilation errors, return to Step 4.
- If
Constraints
- DO check current language version requirements in
pubspec.yamlbefore making any syntax changes. - DO use
@dart = <version>to pin specific files to older versions during migration if a full refactor is not requested. - DO consult breaking change logs before performing major dependency upgrades.
- NEVER use
///or/* */for the@dartversion override comment; it must be//. - NEVER place the
@dartcomment after imports or code declarations. - NEVER attempt to use
dart:html,dart:js, ordart:js_utilwhen compiling to WebAssembly (dart compile wasm). - NEVER disable sound null safety in Dart 3.0+; the
--no-sound-null-safetyflag and unsound execution are completely removed.