Skip to content
Back to skills

Effective Dart

ASecurity

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

  • 639 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added August 31, 2026
ai-agentsbashtestingrefactoringgitapidocumentation

Works with

  • api

Security analysis

A100/100

Scanned August 31, 2026

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

Installs into .claude/skills of the current project.

Are you the author of Effective Dart?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Effective Dart
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/evanca-effective-dart/badge)](https://www.skillsdirectory.com/skills/evanca-effective-dart)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
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.

```dart
// 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

```bash
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

```dart
// 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

```dart
/// 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 doc comments **before** metadata annotations.
- Document **why** code exists or how it should be used, not just what it does.

---

## 8. Testing Patterns

- Write **unit tests** for business logic, using `group` and descriptive `test` names:

```dart
import 'package:test/test.dart';

void main() {
  group('CartService', () {
    late CartService cart;

    setUp(() => cart = CartService());

    test('addItem increases item count', () {
      cart.addItem(Product(id: '1', name: 'Widget', price: 9.99));
      expect(cart.items, hasLength(1));
    });

    test('removeItem decreases total price', () {
      final product = Product(id: '1', name: 'Widget', price: 9.99);
      cart.addItem(product);
      cart.removeItem(product.id);
      expect(cart.totalPrice, equals(0.0));
    });
  });
}
```

- Write **widget tests** using `testWidgets` and `WidgetTester`:

```dart
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('LoginButton shows loading indicator when tapped',
      (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: LoginScreen()));
    await tester.tap(find.byType(ElevatedButton));
    await tester.pump();
    expect(find.byType(CircularProgressIndicator), findsOneWidget);
  });
}
```

---

## 9. Code Review Workflow

When reviewing Dart code for Effective Dart compliance, the agent should check:

1. **Naming** — verify all identifiers follow the conventions in Section 1.
2. **Type annotations** — confirm public API parameters, return types, and uninitialized variables are annotated.
3. **Class modifiers** — verify `final`, `sealed`, or `interface` is used where appropriate.
4. **Documentation** — confirm all public members have `///` doc comments with a single-sentence summary.
5. **Style** — run `dart format --output=none --set-exit-if-changed .` to verify formatting.
6. **Analysis** — run `dart analyze` and confirm zero issues.

---

## References

- [Effective Dart](https://dart.dev/effective-dart)
- [Dart Site WWW GitHub Repository](https://github.com/dart-lang/site-www)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.