A comprehensive, enterprise-grade linting package for Flutter projects that ensures code quality, performance, security, and accessibility compliance.
- avoid_empty_catch_blocks - Prevents silent error swallowing
- avoid_long_methods - Enforces method length limits (default: 50 lines)
- avoid_magic_numbers - Requires constants for hardcoded numbers
- avoid_nested_conditionals - Limits conditional nesting depth
- prefer_early_return - Encourages guard clauses
- prefer_single_widget_per_file - Promotes better organization
- prefer_trailing_commas - Ensures consistent formatting
- prefer_slivers_over_columns - Optimizes scrolling performance for long lists
- avoid_widget_rebuilds - Detects unnecessary widget rebuilds
- prefer_stateless_widgets - Suggests StatelessWidget when appropriate
- avoid_build_context_across_async - Prevents common async context errors
- enforce_layer_dependencies - Validates clean architecture layer dependencies
- avoid_hardcoded_secrets - Detects API keys, passwords, and other secrets
- Comprehensive Analysis - Multi-dimensional code quality assessment
- Performance Profiling - Widget tree optimization and memory leak detection
- Security Scanning - Vulnerability assessment and secret detection
- Accessibility Compliance - WCAG guidelines validation
- Interactive Reports - HTML/JSON/Markdown report generation
Add this to your package's pubspec.yaml:
dev_dependencies:
custom_lint: ^0.6.4
flutter_quality_lints: ^0.9.1Create or update your analysis_options.yaml:
analyzer:
plugins:
- custom_lint
custom_lint:
rules:
# Recommended preset (10 rules)
- avoid_empty_catch_blocks
- avoid_magic_numbers
- prefer_early_return
- prefer_trailing_commas
- avoid_widget_rebuilds
- prefer_stateless_widgets
- avoid_build_context_across_async
- avoid_hardcoded_secrets
- enforce_layer_dependencies
- prefer_slivers_over_columnsChoose from predefined rule sets:
// In your custom_lint.yaml or analysis_options.yaml
import 'package:flutter_quality_lints/flutter_quality_lints.dart';
// Available presets:
FlutterQualityLints.basicRules // 5 essential rules
FlutterQualityLints.recommendedRules // 10 production-ready rules
FlutterQualityLints.strictRules // All 13 rules
FlutterQualityLints.performanceRules // 4 performance-focused rules
FlutterQualityLints.securityRules // 1 security ruleflutter_quality_lints:
# Core Rules Configuration
avoid_long_methods:
max_lines: 50
exclude_getters: true
exclude_constructors: true
avoid_magic_numbers:
allowed_numbers: [0, 1, -1, 2, 10, 100, 1000]
ignore_in_tests: true
# Performance Rules Configuration
prefer_slivers_over_columns:
max_children: 10
check_scrollable_nesting: true
avoid_widget_rebuilds:
check_const_usage: true
check_inline_functions: true
# Architecture Rules Configuration
enforce_layer_dependencies:
layers:
presentation: ["lib/presentation/", "lib/ui/", "lib/pages/"]
domain: ["lib/domain/", "lib/entities/", "lib/usecases/"]
data: ["lib/data/", "lib/datasources/", "lib/models/"]
dependency_rules:
presentation: ["domain"] # Can only depend on domain
domain: [] # Pure - no dependencies
data: ["domain"] # Can only depend on domain
# Security Rules Configuration
avoid_hardcoded_secrets:
min_secret_length: 10
ignore_test_files: true
check_patterns:
- api_keys
- jwt_tokens
- oauth_tokensThe Flutter Quality Lints CLI provides advanced analysis capabilities:
# Add to pubspec.yaml
dependencies:
flutter_quality_lints: ^0.9.1
# Make CLI executable
chmod +x bin/flutter_quality_lints.dartdart bin/flutter_quality_lints.dart analyze [target_directory]
# Example output:
# Running Flutter Quality Analysis on: lib
# Analysis Results:
# Files analyzed: 25
# Issues found: 12
# Critical: 2
# Warning: 7
# Info: 3
# Quality Score: 9.5/10.0dart bin/flutter_quality_lints.dart performance [target_directory]
# Features:
# Widget Tree Complexity Analysis
# Memory Leak Detection
# Unnecessary Rebuild Detection
# Performance Score Calculationdart bin/flutter_quality_lints.dart optimize [target_directory]
# Provides:
# Widget Optimizations
# State Management Improvements
# Build Context Safety Recommendationsdart bin/flutter_quality_lints.dart security [target_directory]
# Detects:
# Hardcoded Secrets (API keys, passwords)
# Input Validation Issues
# Insecure Network Connectionsdart bin/flutter_quality_lints.dart accessibility [target_directory]
# Validates:
# WCAG AA Compliance
# Semantic Labels
# Color Contrast Ratios
# Focus Managementdart bin/flutter_quality_lints.dart report [html|json|markdown]
# Generates:
# Comprehensive Quality Reports
# Trend Analysis Charts
# Interactive Navigation
# Export to PDF (HTML format)# Preview fixes without applying them
dart bin/flutter_quality_lints.dart fix [target_directory] --dry-run
# Apply automatic fixes
dart bin/flutter_quality_lints.dart fix [target_directory]
# Auto-fixes include:
# - Add const to widget constructors
# - Add trailing commas
# - Convert to StatelessWidget
# - Add mounted checks after async
# - Simplify nested conditionals
# - Extract magic numbers to constants// Bad
Container(width: 250, height: 150);
// Good
class Constants {
static const double cardWidth = 250;
static const double cardHeight = 150;
}
Container(width: Constants.cardWidth, height: Constants.cardHeight);// Bad
String processUser(User? user) {
if (user != null) {
if (user.isActive) {
return user.name;
} else {
return 'Inactive user';
}
} else {
return 'No user';
}
}
// Good
String processUser(User? user) {
if (user == null) return 'No user';
if (!user.isActive) return 'Inactive user';
return user.name;
}// Bad - Performance issue with many children
Column(
children: List.generate(1000, (index) => Text('Item $index')),
)
// Good - Efficient scrolling
CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Text('Item $index'),
childCount: 1000,
),
),
],
)// Bad - Context used after async operation
Future<void> deleteItem() async {
await apiService.deleteItem();
Navigator.of(context).pop(); // Dangerous!
}
// Good - Check if mounted
Future<void> deleteItem() async {
await apiService.deleteItem();
if (mounted) {
Navigator.of(context).pop();
}
}// Bad
const String apiKey = 'sk_live_abcd1234567890';
// Good
final String apiKey = Platform.environment['API_KEY'] ?? '';// Bad - Presentation layer importing data layer
import '../data/user_repository_impl.dart'; // In presentation layer
// Good - Presentation layer importing domain layer
import '../domain/repositories/user_repository.dart'; // In presentation layerThe package provides comprehensive quality scoring:
- Quality Score: Overall code health (0-10.0)
- Performance Score: Widget and rendering efficiency
- Security Score: Vulnerability assessment
- Accessibility Score: WCAG compliance level
Quality Score = 10.0 - (Critical Issues × 2.0 + Warnings × 1.0 + Info × 0.5) / Files Analyzed
# .github/workflows/quality_check.yml
- name: Run Quality Analysis
run: |
dart bin/flutter_quality_lints.dart analyze lib
dart bin/flutter_quality_lints.dart security lib
dart bin/flutter_quality_lints.dart report json > quality_report.json{
"dart.customLintRules": ["flutter_quality_lints"],
"dart.showIgnoreQuickFixes": true
}#!/bin/sh
dart bin/flutter_quality_lints.dart analyze lib
if [ $? -ne 0 ]; then
echo "Quality check failed. Please fix issues before committing."
exit 1
fiFull integration with Dart's built-in analyzer for comprehensive coverage.
Many rules support automatic fixes for common patterns.
Deep analysis of widget trees and rebuild patterns.
Enterprise-grade secret detection with pattern matching.
WCAG 2.1 AA compliance checking with actionable recommendations.
We welcome contributions! Please see our Contributing Guide for details.
git clone https://github.com/dvillegastech/flutter_quality_lints.git
cd flutter_quality_lints
dart pub get
dart testThis project is licensed under the MIT License - see the LICENSE file for details.
Made with by David Villegas