Dart
Dart code, its tools and its packages, for pure Dart and for the Dart inside a Flutter app. A package's language version is the lower bound of environment.sdk in its pubspec.yaml, not the SDK binary you run, and that one value decides which features compile (patterns need 3.0, dot shorthands 3.10, primary constructors 3.13), which breaking changes apply and how dart format lays out the code. Current stable is 3.13.5 (2026-09-29). Widgets, Flutter testing, builds and app releases are in flutter SKILL.md.
Apply only the routes and checks for the selected job. Read a linked skill's named file from its installed folder when available, or from the linked source. Report an unavailable required reference instead of inventing it. [skill-authoring, DISTRIBUTION.md#composing-skills]
| The job | Read |
|---|---|
Feature minimums per language version, class modifiers, sealed and exhaustive switches, modifiers in a published API, extension methods, extension types, dot shorthands, null safety and late |
LANGUAGE.md |
| Records, where patterns appear, switch statement or expression, every pattern type, picking a pattern, anti-patterns, JSON validation | RECORDS-AND-PATTERNS.md |
Primary constructors (3.13), concise new / factory syntax, private named parameters (3.12), the 3.13 extraneous_modifier break, migration and diagnostics |
CONSTRUCTORS.md |
async / await, Future.wait and .wait with ParallelWaitError, Future.any, the Future API and catchError chains, using and creating streams, StreamController, Isolate.run, long-lived isolates and ports |
ASYNC.md |
Adding days across daylight saving, HashMap / LinkedHashMap / SplayTreeMap and map operations, shallow and deep copies of lists and maps, immutable collection packages, JsonEncoder.withIndent, Function.apply, runtime paths with package:path |
CORE-LIBRARIES.md |
Effective Dart Style and Documentation: identifier casing, import ordering, dart format, comments, /// doc comments, references, {@example} |
STYLE-AND-DOCS.md |
| Effective Dart Usage and Design: imports, null, strings, collections, functions, members, constructors, error handling, async, naming APIs, privacy, classes, types, parameters, equality | USAGE-AND-DESIGN.md |
analysis_options.yaml, strict modes, lint sets and their rules, severities and suppression, formatter settings, analyzer plugins, dart analyze, dart fix, dart format, fixing errors, and a pointer to shared MCP setup |
ANALYSIS-AND-LINTS.md |
package:test, layout, running and selecting tests, platforms, skips, timeouts and tags, dart_test.yaml, mockito, migrating to package:checks, coverage |
TESTING.md |
| Pub resolution, dependency sources, version constraints, overrides, pubspec fields, package layout, upgrading and conflicts, workspaces, publishing and automated publishing, shipping agent skills | PACKAGES.md |
The dart command, CLI project setup, exit codes, stdout and stderr, package:args, stack traces, subprocesses and finding the SDK, signals, testing CLIs, dart run, dart install, dart build and dart compile |
CLI-APPS.md |
| Build hooks and native assets, compiling C locally with tree shaking, precompiled downloads with hash checks, generating bindings with ffigen, shipping | FFI.md |
| Current channels, release dates, language version rules, changes and breaking changes per version, experiments, why macros will not ship, upgrading old code | VERSIONS.md |
The rules
- Check the package's language version before using a feature: the
environment.sdklower bound must be at least the version that introduced it, per package, even inside a workspace. - Keep analysis clean: an
analysis_options.yamlat the package root that includespackage:lints/recommended.yaml(orpackage:flutter_lints/flutter.yaml), thendart analyze,dart fix --dry-runbeforedart fix --apply, anddart format, whose output is the official whitespace style. - Await every future or leave it unawaited on purpose, catch errors where the
awaitor the stream listener is, and move long synchronous work off the main isolate withIsolate.runso the UI does not jank. - Use patterns where they replace
is/aschains and length checks, switch exhaustively oversealedfamilies, and fail fast withFormatExceptionon malformed data instead of letting anif-caseskip it. - Test through constructor-injected dependencies: tests under
test/mirroringlibwith a_test.dartsuffix, mocks from@GenerateNiceMocks, andthenAnswer(neverthenReturn) for anything returning aFutureorStream. - Never delete the whole
pubspec.lockto fix a conflict; delete only the conflicting package's block and rundart pub get. Use caret constraints with the widest range that works, and commitpubspec.lockfor applications only. - In a CLI, set
exitCodeand letmain()return instead of callingexit(), which skipsfinallyblocks, drops buffered output and zeroes coverage. Send results tostdoutand errors and usage tostderr, and finddartwithpackage:cli_util, neverPlatform.resolvedExecutable. - Never hand-write FFI bindings when headers exist: generate them with ffigen, build native code through build hooks and
package:native_toolchain_c, and usedart build(notdart compile exe) once any dependency has hooks.
Prove it
dart analyze --fatal-infos exits 0; dart format -o none --set-exit-if-changed . exits 0; dart test passes; dart pub get --enforce-lockfile succeeds in CI; every package's environment.sdk lower bound covers the features its code uses; and every file's own Prove it checks pass for the parts you touched.