
Effective Dart
- 46 installs
- 605 repo stars
- Updated August 4, 2026
- evanca/flutter-ai-rules
Helps with ai & agent building tasks.
About
effective-dart is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- effective-dart
- AI & Agent Building
- AI-coding skill
Effective Dart by the numbers
- 46 all-time installs (skills.sh)
- Ranked #7,629 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/evanca/flutter-ai-rules --skill effective-dartAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 46 |
|---|---|
| repo stars | ★ 605 |
| Last updated | August 4, 2026 |
| Repository | evanca/flutter-ai-rules ↗ |
What it does
Helps with ai & agent building tasks.
Files
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, notHTTPRequest. - 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.
---
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
dynamicinstead 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.
// 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
finalovervarwhen variable values won't change. - Use
constfor compile-time constants. - Prefer lines 80 characters or fewer for readability.
---
4. Imports and Files
- Don't import libraries inside the
srcdirectory 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
constif 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
varandfinalon local variables. - Initialize fields at their declaration when possible.
- Override
hashCodeif you override==; ensure==obeys mathematical equality rules. - Prefer specific exception handling: use
on SomeException catch (e)instead of broadcatch (e)or.catchErrorhandlers.
---
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 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
groupand descriptivetestnames:
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
testWidgetsandWidgetTester:
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.
---