Skip to content
Development
Skill

/effective-dart

Use when writing Dart code, reviewing for style, refactoring naming, adding doc comments, structuring imports, or enforcing type annotations.

From plugin
flutter-ai-skills
67036 skills

Claude Code

$ npx -y skills add evanca/flutter-ai-rules --skill effective-dart --agent claude-code

SKILL.md

effective-dart.SKILL.md
name: effective-dart
description: "Use when writing Dart code, reviewing for style, refactoring naming, adding doc comments, structuring imports, or enforcing type annotations."
license: MIT

Effective Dart Skill

This skill defines how to write idiomatic, high-quality Dart and Flutter code following Effective Dart guidelines.

---

1. Naming Conventions

| Kind | Convention | Example | |---|---|---| | Classes, enums, typedefs, type parameters, extensions | `UpperCamelCase` | `MyWidget`, `UserState` | | Packages, directories, source files | `lowercase_with_underscores` | `user_profile.dart` | | Import prefixes | `lowercase_with_underscores` | `import '...' as my_prefix;` | | Variables, parameters, named parameters, functions | `lowerCamelCase` | `userName`, `fetchData()` |

  • Capitalize acronyms and abbreviations longer than two letters like words: `HttpRequest`, not `HTTPRequest`.
  • Avoid abbreviations unless the abbreviation is more common than the full term.
  • Prefer putting the **most descriptive noun last** in names.
  • Use terms **consistently** throughout your code.
  • Follow mnemonic conventions for type parameters: `E` (element), `K`/`V` (key/value), `T`/`S`/`U` (generic types).
  • Consider making code **read like a sentence** when designing APIs.
  • Prefer a **noun phrase** for non-boolean properties or variables.
  • Prefer a **non-imperative verb phrase** for boolean properties or variables; prefer the positive form.
  • Consider omitting the verb for named boolean parameters.
  • Avoid starting a function or method name with `get`; prefer removing `get` and using a getter when the API conceptually exposes a property.

---

2. Types and Functions

  • Use **class modifiers** (`final`, `sealed`, `interface`, `base`, `mixin`) to control whether a class can be extended or implemented.
  • **Type annotate variables** without initializers.
  • Type annotate **fields and top-level variables** if the type isn't obvious.
  • **Annotate return types** on function declarations.
  • **Annotate parameter types** on function declarations.
  • Write **type arguments** on generic invocations that aren't inferred.
  • Annotate with `dynamic` instead of letting inference fail.
  • Use `Future<void>` as the return type of async members that do not produce values.
  • Use **getters** for operations that conceptually access properties.
  • Use **setters** for operations that conceptually change properties.
  • Use a **function declaration** to bind a function to a name.
  • Use **inclusive start and exclusive end** parameters to accept a range.
  • Don't annotate a **return type on a setter** — including the `[]=` operator, which behaves like a setter.
// Prefer: explicit class modifier
final class AppConfig {
  final String apiUrl;
  final int timeout;
  const AppConfig({required this.apiUrl, required this.timeout});
}

// Prefer: sealed for exhaustive pattern matching
sealed class Result<T> {}
class Success<T> extends Result<T> { final T value; Success(this.value); }
class Failure<T> extends Result<T> { final Exception error; Failure(this.error); }

---

3. Style

dart format .
  • Format code with `dart format` — don't manually format.
  • Use **curly braces** for all flow control statements.
  • Prefer `final` over `var` when variable values won't change.
  • Use `const` for compile-time constants.
  • Prefer lines **80 characters or fewer** for readability.

---

4. Imports and Files

  • Don't import libraries inside the `src` directory of another package.
  • Don't allow import paths to reach into or out of `lib`.
  • **Prefer relative import paths** within a package.
  • Don't use `/lib/` or `../` in import paths.
  • Consider writing a **library-level doc comment** for library files.

---

5. Structure

  • Keep files **focused on a single responsibility**.
  • Limit file length to maintain readability.
  • Group related functionality together.
  • Prefer making fields and top-level variables `final`.
  • Consider making constructors `const` if the class supports it.
  • **Prefer making declarations private** — only expose what's necessary.

---

6. Usage Patterns

// Adjacent string concatenation (not +)
final greeting = 'Hello, '
    'world!';

// Collection literals
final list = [1, 2, 3];
final map = {'key': 'value'};

// Initializing formals
class Point {
  final double x, y;
  Point(this.x, this.y);
}

// Empty constructor body
class Empty {
  Empty();  // not Empty() {}
}

// rethrow to preserve stack trace
try {
  doSomething();
} catch (e) {
  log(e);
  rethrow;
}
  • Use `whereType<T>()` to filter a collection by type.
  • Follow a **consistent rule** for `var` and `final` on local variables.
  • Initialize fields at their **declaration** when possible.
  • Override `hashCode` if you override `==`; ensure `==` obeys mathematical equality rules.
  • **Prefer specific exception handling**: use `on SomeException catch (e)` instead of broad `catch (e)` or `.catchError` handlers.

---

7. Documentation

/// Returns the sum of [a] and [b].
///
/// Throws [ArgumentError] if either value is negative.
int add(int a, int b) { ... }
  • Format comments like sentences (capitalize, end with period).
  • Use `///` doc comments — not `/* */` block comments — for types and members.
  • Prefer writing doc comments for **public APIs**; consider them for private APIs too.
  • Start doc comments with a **single-sentence summary**, separated into its own paragraph.
  • Avoid redundancy with the surrounding context.
  • Start function/method comments with a **third-person verb** if the main purpose is a side effect.
  • Start with a **noun or non-imperative verb phrase** if returning a value is the primary purpose.
  • Start **boolean** variable/property comments with "Whether" followed by a noun or gerund phrase.
  • Use `[identifier]` in doc comments to refer to in-scope identifiers.
  • Use **prose** to explain parameters, return values, and exceptions (e.g., "The [param]", "Returns", "Throws" sections).
  • Put
Read more
@evanca
Ships withflutter-ai-skills

36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documentation. A skill is a folder with a SKILL.md file.

Stars on GitHub

Momentum

stars in total
670
Star history of evanca/flutter-ai-rules on GitHub, a chart by star-history.com

Other skills on flutter-ai-skills.

accessibility

accessibility

Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…

bloc

bloc

Use when creating a Cubit or Bloc, modeling state with sealed classes or status enums, wiring…

dart-3-updates

dart-3-updates

Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about effective-dart.

Which coding agents can use effective-dart?
effective-dart installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.