evanca/flutter-ai-rules/dart-3-updates
Claude Code and agent skill by evanca/flutter-ai-rules
- community
Checking that the SKILL.md file is still in the repository.
Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring values, or modernizing pre-Dart-3 code.
Install
npx vskill@latest install evanca/flutter-ai-rules/dart-3-updatesSKILL.md
Dart 3 Updates Skill
Apply Dart 3 language features — branches, patterns, pattern types, and records — correctly and idiomatically.
When to Use
Use this skill when:
- Writing or refactoring
switchstatements orif-elsechains. - Creating new data-holding classes and deciding between sealed classes, records, or plain classes.
- Destructuring values from maps, lists, records, or objects.
- Modernizing pre-Dart-3 code to use patterns, exhaustiveness checks, or switch expressions.
1. Branches
if / if-case
ifconditions must evaluate to abool.- In
if-case, variables declared in the pattern are scoped to the matching branch. - If the pattern does not match, control flows to the
elsebranch (if present).
switch statements
- Each matched
casebody executes and jumps to the end —breakis not required. - Non-empty cases can end with
continue,throw, orreturn. - Use
defaultor_to handle unmatched values. - Empty cases fall through; use
breakto prevent fallthrough in an empty case. - Use
continuewith a label for non-sequential fallthrough. - Use logical-or patterns (
case a || b) to share a body between cases.
switch expressions
- Omit
case; use=>for bodies; separate cases with commas. - Default must use
_(notdefault). - Produces a value.
Exhaustiveness
- Dart checks exhaustiveness in
switchstatements and expressions at compile time. - Use
default/_, enums, orsealedtypes to satisfy exhaustiveness.
Guard clauses
- Add
when conditionafter a pattern to further constrain matching. - Usable in
if-case,switchstatements, andswitchexpressions. - If the guard is
false, execution proceeds to the next case.
2. Patterns
Patterns represent the shape of a value for matching and destructuring.
Uses
- Wildcard
_ignores parts of a matched value. - Rest elements (
...) in list patterns ignore remaining elements. - Case patterns are refutable: if no match, execution continues to the next case.
- Destructured values in a case become local variables scoped to that case body.
Object patterns
JSON / nested data validation
3. Pattern Types
| Pattern | Syntax | Description | |||
|---|---|---|---|---|---|
| Logical-or | `p1 \ | \ | p2` | Matches if any branch matches. All branches must bind the same variables. | |
| Logical-and | p1 && p2 | Matches if both match. Variable names must not overlap. | |||
| Relational | == c, < c, >= c | Compares value to a constant. Combine with && for ranges. | |||
| Cast | subpattern as Type | Asserts type, then matches inner pattern. Throws if type mismatch. | |||
| Null-check | subpattern? | Matches non-null; binds non-nullable type. | |||
| Null-assert | subpattern! | Matches non-null or throws. Use in declarations to eliminate nulls. | |||
| Constant | 42, 'str', const Foo() | Matches if value equals the constant. | |||
| Variable | var name, final Type name | Binds matched value to a new variable. Typed form only matches the declared type. | |||
| Wildcard | _, Type _ | Matches any value without binding. | |||
| Parenthesized | (subpattern) | Controls precedence. | |||
| List | [p1, p2] | Matches lists by position. Length must match unless a rest element is used. | |||
| Rest element | ..., ...rest | Matches arbitrary-length tails or collects remaining elements. | |||
| Map | {'key': subpattern} | Matches maps by key. Missing keys throw StateError. | |||
| Record | (p1, p2), (x: p1, y: p2) | Matches records by shape; field names can be omitted if inferred. | |||
| Object | ClassName(field: p) | Matches by type and destructures via getters. Extra fields ignored. |
- Use parentheses to group lower-precedence patterns.
- All pattern types can be nested and combined.
4. Records
- Records are anonymous, immutable, fixed-size aggregates.
- Each field can have a different type (heterogeneous).
- Fields are accessed via built-in getters (
$1,$2,.name); no setters. - Two records are equal if they have the same shape and equal field values.
hashCodeand==are automatically defined.
Multiple return values
Records vs. data classes
Use a record when:
- Returning multiple values from a single function (small, one-time use).
- Grouping a few values locally with no reuse across the codebase.
- You need structural equality with no additional behavior.
Use a class when:
- The type is reused across multiple files or features.
- You need methods, encapsulation, inheritance, or
copyWith. - The type is part of a public API or long-lived data model.
- Changing the shape must be caught by the type system across the codebase.
Other best practices
- Use
typedeffor record types to improve readability and maintainability. - Changing a record type alias does not guarantee type safety across the codebase — only classes provide full abstraction.
5. Migration Workflow
When modernizing pre-Dart-3 code, follow these steps:
Step 1 — Replace if-else chains with switch expressions
Step 2 — Convert abstract class hierarchies to sealed classes
Step 3 — Use destructuring for multiple return values
Replace wrapper classes used solely for returning multiple values with records.
Step 4 — Validate
Run dart analyze to confirm exhaustiveness and type safety after each change.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/dart-3-updates/SKILL.md
Popularity
- Repository stars
- 500
- Repository forks
- 51
- 7-day trend score
- 31
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 24 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/evanca/flutter-ai-rules/dart-3-updates)