Dart Standards
Dart Standards
Section titled “Dart Standards”1. Package Management
Section titled “1. Package Management”- Tool:
pub(Dart’s package manager).pubspec.yamlfor dependencies. - Version: Dart 3.0+ (null safety required).
- Dependencies: Declare in
pubspec.yaml. Pin versions for production.
2. Code Style
Section titled “2. Code Style”- Formatter:
dart format. Run viamake fmt. - Linter:
dart analyzewithanalysis_options.yaml. Uselinterpackage rules. - Type Checker: Strong mode enabled by default. No implicit
dynamic.
analysis_options.yaml
Section titled “analysis_options.yaml”include: package:linter/analyzer.yaml
linter: rules: - always_declare_return_types - avoid_empty_else - prefer_const_constructors - prefer_final_fields
analyzer: errors: missing_return: error exclude: - build/**3. Naming Conventions
Section titled “3. Naming Conventions”- Files:
snake_case.dart - Classes/Enums:
PascalCase - Variables/Functions:
camelCase - Constants:
lowerCamelCase(useconstorstatic const) - Private:
_leadingUnderscorefor library-private
4. Project Structure
Section titled “4. Project Structure”lib/├── domain/│ ├── entities/│ └── value_objects/├── application/│ ├── use_cases/│ └── interfaces/└── infrastructure/ └── repositories/
test/└── [Mirror lib structure]5. Language Features
Section titled “5. Language Features”- Null Safety: Use nullable types (
String?). Use!for null assertion sparingly. - Immutability: Prefer
finalovervar. Useconstconstructors when possible. - Records: Use
record(Dart 3.0+) for value objects and data transfer. - Patterns: Use pattern matching (Dart 3.0+) for destructuring and matching.
Example
Section titled “Example”class Email { final String value;
Email(this.value) { if (!value.contains('@') || !value.contains('.')) { throw InvalidEmailException(value); } }}
sealed class Result<T> { const Result();}
class Success<T> extends Result<T> { final T data; const Success(this.data);}
class Failure<T> extends Result<T> { final Exception error; const Failure(this.error);}6. Dependency Injection
Section titled “6. Dependency Injection”- Framework: Use
get_itorinjectablefor DI. Prefer constructor injection. - Code Generation: Use
build_runnerfor generated code (annotations).
7. Testing
Section titled “7. Testing”- Framework:
testpackage. Useexpect()for assertions. - Mocking:
mockitowith code generation. Use@GenerateMocksannotation. - Coverage:
test_coverage. 95% is the absolute minimum for any module. Target 100% for domain, 95%+ for application and infrastructure.
Test Structure
Section titled “Test Structure”import 'package:test/test.dart';import 'package:mockito/annotations.dart';import 'package:mockito/mockito.dart';
@GenerateMocks([UserRepository])void main() { group('UserService', () { test('should create user with valid email', () { // Given final email = Email('test@example.com');
// When final user = UserService.createUser(email, 'Test User');
// Then expect(user.email.value, equals('test@example.com')); }); });}8. Error Handling
Section titled “8. Error Handling”- Exceptions: Use typed exceptions extending
ExceptionorError. - Result Pattern: Use
Result<T>sealed class for functional error handling. - Async Errors: Use
Future<T>with error handling orResult<Future<T>>.
class DomainException implements Exception { final String message; DomainException(this.message);
@override String toString() => 'DomainException: $message';}
class InvalidEmailException extends DomainException { InvalidEmailException(String email) : super('Invalid email: $email');}9. Async/Await
Section titled “9. Async/Await”- Futures: Use
Future<T>for async operations. Preferasync/awaitover.then(). - Streams: Use
Stream<T>for reactive data. UseStreamControllerfor custom streams. - Isolates: Use
Isolate.spawn()for CPU-intensive tasks.
Future<User> fetchUser(String id) async { try { final user = await userRepository.findById(id); return user ?? throw UserNotFoundException(id); } catch (e) { throw UserFetchException('Failed to fetch user: $id', e); }}10. Dependencies
Section titled “10. Dependencies”Common Libraries
Section titled “Common Libraries”- HTTP:
httppackage ordiofor advanced features - JSON:
json_serializablewith code generation - State Management:
riverpodorbloc(Flutter),get_it(server) - Logging:
loggerpackage
11. Documentation
Section titled “11. Documentation”- Doc Comments: Use triple-slash (
///) for documentation. Supports Markdown. - Format: Use
[param],[returns],[throws]tags.
/// Creates a new user with validated email address.////// [email] Valid email address (must match RFC 5322)/// [name] User's full name (non-null, non-empty)////// Returns new User entity instance.////// Throws [InvalidEmailException] if email format is invalid.User createUser(Email email, String name) { // Implementation}12. Flutter-Specific
Section titled “12. Flutter-Specific”- Widgets: Use
constconstructors when possible. PreferStatelessWidgetoverStatefulWidget. - State Management: Use
riverpodorblocfor complex state. AvoidsetStatefor business logic. - Testing: Use
flutter_testfor widget tests. Usegoldentests for UI regression.
13. Server-Side
Section titled “13. Server-Side”- Framework: Use
shelfordart_frogfor HTTP servers. - Isolates: Leverage isolates for concurrent request handling.
- Database: Use
postgresormongo_dartpackages.