awesome_lints 2.0.0
awesome_lints: ^2.0.0 copied to clipboard
Comprehensive custom lint rules for Dart and Flutter.
Awesome Lints #
A comprehensive collection of custom lint rules for Dart and Flutter applications, built on top of the custom_lint package. These rules help you write cleaner, more maintainable, and bug-free code by catching common mistakes and enforcing best practices.
Features #
- 🎯 32 Flutter-specific lints - Catch Flutter widget issues, lifecycle problems, and performance pitfalls
- 🔍 54 Common Dart lints - General-purpose rules for any Dart codebase
- 📦 8 Provider-specific lints - Best practices for the Provider state management package
- 🧊 22 Bloc-specific lints - Best practices for the Bloc state management package
- ⏱️ 1 FakeAsync-specific lint - Catch common testing mistakes with fake_async
- ⚡ Fast analysis - Built on custom_lint for efficient, real-time feedback
- 🛠️ Easy to configure - All rules enabled by default, with optional customization
- 📚 Well-documented - Every rule includes examples and explanations
Quick Start #
Installation #
- Add
awesome_lintsandcustom_lintto yourpubspec.yaml:
dev_dependencies:
awesome_lints:
path: path/to/awesome_lints # or use git/pub dependency
custom_lint: ^0.7.0
- Enable the custom_lint plugin in your
analysis_options.yaml:
analyzer:
plugins:
- custom_lint
- Run the linter:
# Analyze your project
dart run custom_lint
# Or with auto-fix support (where available)
dart run custom_lint --fix
Usage in IDE #
VS Code: Install the Dart extension - custom_lint diagnostics will appear automatically.
Android Studio / IntelliJ: Custom lint diagnostics will appear in the editor alongside standard Dart analysis.
Watch Mode: For continuous analysis during development:
dart run custom_lint --watch
Available Lints #
Flutter-Specific Rules #
32 rules designed specifically for Flutter applications, covering:
- Widget lifecycle and state management
- Performance optimization
- Common Flutter anti-patterns
- Resource disposal
- Builder patterns and best practices
📖 View all Flutter lints →
Popular rules include:
avoid-late-context- Prevents context usage in late field initializersavoid-mounted-in-setstate- Ensures proper mounted checksprefer-spacing- Use Flutter 3.27+ spacing parameterpass-existing-future-to-future-builder- Prevents future recreation on rebuildprefer-container- Suggests simplifying nested widgets
Common Dart Rules #
54 rules applicable to any Dart codebase, covering:
- Code quality and maintainability
- Logic errors and potential bugs
- Performance considerations
- Code style and consistency
- Null safety best practices
📖 View all Common lints →
Popular rules include:
avoid-non-null-assertion- Warns about unsafe!operator usagearguments-ordering- Enforces parameter order consistencyno-equal-then-else- Detects identical if/else branchesavoid-collection-equality-checks- Prevents identity vs value equality bugsno-magic-number- Requires named constants for numeric literals
Provider Rules #
8 rules designed specifically for applications using the Provider package:
- Provider usage patterns and best practices
- Memory leak prevention
- Correctness checks for read/watch usage
- Code maintainability improvements
📖 View all Provider lints →
Popular rules include:
avoid-read-inside-build- Prevents read() usage in build methodsavoid-watch-outside-build- Ensures watch() is only used in builddispose-providers- Checks for proper resource disposalprefer-multi-provider- Suggests MultiProvider over nested providersprefer-provider-extensions- Prefers context.read/watch over Provider.of
Bloc Rules #
22 rules designed specifically for applications using the Bloc package:
- Bloc/Cubit usage patterns and best practices
- Encapsulation and architectural correctness
- Event and state management
- Memory leak prevention
- Immutability enforcement
📖 View all Bloc lints →
Popular rules include:
avoid-bloc-public-fields- Enforces private fields in Blocs/Cubitsavoid-bloc-public-methods- Prevents public methods except overridesavoid-passing-build-context-to-blocs- Prevents BuildContext couplingprefer-immutable-bloc-events- Requires @immutable on event classesprefer-sealed-bloc-state- Requires sealed/final modifiers on state classes
FakeAsync Rules #
1 rule designed specifically for applications using the fake_async package for testing:
- Correctness checks for FakeAsync usage
- Prevent tests from always passing
- Ensure proper async testing patterns
📖 View all FakeAsync lints →
Rules include:
avoid-async-callback-in-fake-async- Prevents async callbacks in FakeAsync that aren't awaited
Configuration #
All lints are enabled by default. To customize rule behavior or disable specific rules, add configuration to your analysis_options.yaml:
custom_lint:
rules:
# Disable a specific rule
- avoid_non_null_assertion: false
# Configure rule parameters (if supported)
- no_magic_number:
allowed_numbers: [0, 1, -1, 100]
Development #
Project Structure #
awesome_lints/
├── lib/
│ └── src/
│ ├── lints/
│ │ ├── flutter/ # Flutter-specific lints
│ │ │ ├── FLUTTER_LINTS.md
│ │ │ └── *.dart
│ │ ├── common/ # Common Dart lints
│ │ │ ├── COMMON_LINTS.md
│ │ │ └── *.dart
│ │ ├── provider/ # Provider-specific lints
│ │ │ ├── PROVIDER_LINTS.md
│ │ │ └── *.dart
│ │ ├── bloc/ # Bloc-specific lints
│ │ │ ├── BLOC_LINTS.md
│ │ │ └── *.dart
│ │ └── fake_async/ # FakeAsync-specific lints
│ │ ├── FAKE_ASYNC_LINTS.md
│ │ └── *.dart
│ └── awesome_lints_plugin.dart
├── test/
│ └── fixtures/
│ └── test_project/ # Test cases for all rules
└── README.md
Adding a New Lint Rule #
-
Create the rule file:
- For Flutter rules:
lib/src/lints/flutter/your_rule_name.dart - For common rules:
lib/src/lints/common/your_rule_name.dart - For Provider rules:
lib/src/lints/provider/your_rule_name.dart - For Bloc rules:
lib/src/lints/bloc/your_rule_name.dart - For FakeAsync rules:
lib/src/lints/fake_async/your_rule_name.dart
- For Flutter rules:
-
Implement the
DartLintRuleclass:
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';
class YourRuleName extends DartLintRule {
const YourRuleName() : super(code: _code);
static const _code = LintCode(
name: 'your_rule_name',
problemMessage: 'Description of the problem',
correctionMessage: 'How to fix it',
errorSeverity: DiagnosticSeverity.WARNING,
);
@override
void run(
CustomLintResolver resolver,
DiagnosticReporter reporter,
CustomLintContext context,
) {
// Your lint logic here
}
}
-
Register the rule:
- Add export to
lib/src/lints/flutter/flutter.dart,lib/src/lints/common/common.dart,lib/src/lints/provider/provider.dart,lib/src/lints/bloc/bloc.dart, orlib/src/lints/fake_async/fake_async.dart - Add the rule instance in
lib/src/awesome_lints_plugin.dart
- Add export to
-
Create test fixtures:
test/fixtures/test_project/lib/your_rule_name/
├── should_trigger_lint.dart # Use // expect_lint: your_rule_name
└── should_not_trigger_lint.dart # Valid code that shouldn't trigger
- Document the rule:
- Add entry to
FLUTTER_LINTS.md,COMMON_LINTS.md,PROVIDER_LINTS.md,BLOC_LINTS.md, orFAKE_ASYNC_LINTS.md - Include "Why?", "Bad", and "Good" examples
- Add entry to
Running Tests #
# Navigate to test project
cd test/fixtures/test_project
# Install dependencies
flutter pub get
# Run the linter (this validates all test fixtures)
dart run custom_lint
Expected output: Lints should only appear on lines marked with // expect_lint: rule_name.
Testing Locally #
To test your rules in a real project:
# In your test project's pubspec.yaml
dev_dependencies:
awesome_lints:
path: /absolute/path/to/awesome_lints
custom_lint: ^0.7.0
Requirements #
- Dart SDK: 3.0.0 or higher
- Flutter SDK: 3.0.0 or higher (for Flutter-specific rules)
- custom_lint: ^0.7.0
Contributing #
Contributions are welcome! When submitting new rules:
- Ensure the rule catches real-world problems or enforces valuable best practices
- Provide clear documentation with examples
- Include comprehensive test fixtures
- Follow the existing code structure and style
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Resources #
Acknowledgments #
Built with custom_lint by Invertase.