Getting Started¶
Minimum Requirements¶
- Dart SDK: ^3.8.0
1. Detect your architecture¶
Read your pubspec.yaml to extract the app name and SDK constraint, then scan the lib/ directory to identify your project’s architecture pattern:
| Signal | Likely pattern |
|---|---|
lib/ has data/, domain/, presentation/ |
Clean Architecture |
lib/ has data/, domain/, ui/ or views/ |
Clean Architecture (variant) |
Files named *viewmodel.dart, *screen.dart |
MVVM |
Files named *_cubit.dart, *_state.dart |
BLoC / Cubit |
Files named *_controller.dart |
GetX or Controller-based |
Files named *_provider.dart, *_notifier.dart |
Provider / Riverpod |
Directories named by feature (e.g. auth/, home/) |
Feature-based |
lib/ has models/, repositories/, services/, utils/ |
Layer-based |
2. Create eagle_eye_config.json¶
Create this file at the project root (same directory as pubspec.yaml). It is a JSON array of rule objects.
Rule types¶
| Key | Type | Effect |
|---|---|---|
filePattern |
string | Wildcard pattern matching file paths. * becomes .* regex. |
dependenciesAllowed |
boolean | If false, matched files must have zero internal imports. |
forbiddenDependencies |
string[] | Matched files must not import anything matching these patterns. |
exclusiveDependencies |
string[] | Matched files can only import things matching any of these patterns (or nothing at all). |
name |
string | Optional human-readable name (shown in violation output). |
Architecture-specific templates¶
Pick and adapt the template that matches your architecture.
Clean Architecture (data/, domain/, presentation/)¶
[
{
"filePattern": "*/domain/model/*",
"dependenciesAllowed": false,
"name": "domain-models-no-imports"
},
{
"filePattern": "*/domain/*_repository.dart",
"exclusiveDependencies": ["*/data/*"],
"name": "repositories-only-data"
},
{
"filePattern": "*/presentation/*",
"forbiddenDependencies": ["*/data/*"],
"name": "presentation-no-data"
}
]
MVVM (*viewmodel.dart, *screen.dart)¶
[
{
"filePattern": "*viewmodel.dart",
"forbiddenDependencies": ["*_screen.dart"],
"name": "viewmodels-no-screens"
},
{
"filePattern": "*screen.dart",
"exclusiveDependencies": ["*_viewmodel.dart", "*_widget.dart"],
"name": "screens-only-widgets-and-viewmodels"
}
]
Feature-based (directories named by feature)¶
[
{
"filePattern": "*/features/*/data/*",
"exclusiveDependencies": ["*/features/*/domain/*"],
"name": "feature-data-depends-on-domain"
},
{
"filePattern": "*/features/*/domain/*",
"dependenciesAllowed": false,
"name": "feature-domain-no-imports"
}
]
Generic / starter config¶
If the architecture is unclear or doesn’t match a specific pattern, use this conservative starter:
[
{
"filePattern": "*/model/*",
"dependenciesAllowed": false,
"name": "models-no-imports"
},
{
"filePattern": "*/data/*_repository.dart",
"exclusiveDependencies": ["*_datasource.dart"],
"name": "repositories-only-datasources"
}
]
Customization guidelines¶
- Start with a small set of rules (2-4). You can add more as your architecture stabilizes.
filePatternmatches against the full file path relative tolib/. Use*as a wildcard.- Each file must match at most one rule. EagleEye validates the configuration before analyzing imports and exits with code 1 when a file matches more than one rule.
- Only internal imports (those containing your app name) are checked. External package imports are ignored.
- Each rule object must have at most one of:
dependenciesAllowed,forbiddenDependencies, orexclusiveDependencies. EagleEye also rejects empty or invalidfilePatternvalues and invalid dependency patterns.
3. Configure analysis_options.yaml¶
Eagle Eye requires package-style imports (not relative imports). Ensure this lint rule is set to error.
If the file does not exist, create it:
analyzer:
errors:
avoid_relative_lib_imports: error
If the file already exists, add or merge the errors section:
analyzer:
errors:
avoid_relative_lib_imports: error
# ... other existing error rules
This enforces imports like:
// GOOD - package import
import 'package:my_app/utils/helper.dart';
// BAD - relative import
import '../utils/helper.dart';
4. Add Eagle Eye dependency¶
Add to pubspec.yaml under dev_dependencies:
dev_dependencies:
# ... existing dev dependencies
eagle_eye: ^2.0.4
Then run:
dart pub get
Or for Flutter projects:
flutter pub get
5. Validate the setup¶
Run the CLI:
dart run eagle_eye:main
- Exit code 0 with a success message: setup is correct.
- Exit code 1 with violations listed: the rules are working — review the violations to confirm they are real issues or adjust your config.
To see every configuration, file, import, and pattern check performed, run:
dart run eagle_eye:main --verbose
Verbose lines are prefixed with [verbose]. Use --help (or -h) to list the
available options.
To analyze only specific files, pass their paths:
dart run eagle_eye:main lib/data/user_repository.dart lib/model/user.dart
Paths must exist, end with .dart, and live under lib/. When no paths are
provided, EagleEye scans every Dart file in lib/.
6. Optional — integrate into CI/CD¶
Add to your CI pipeline (e.g. GitHub Actions, GitLab CI):
- name: Check architecture rules
run: dart run eagle_eye:main
Eagle Eye exits with code 1 on violations, so the CI step will fail automatically if architecture rules are broken.
Summary¶
| File | Action | Purpose |
|---|---|---|
eagle_eye_config.json |
Create | Architecture rules |
analysis_options.yaml |
Create or modify | Enable avoid_relative_lib_imports: error |
pubspec.yaml |
Modify | Add eagle_eye as dev dependency |
After completing all steps, run dart run eagle_eye:main to confirm everything works.
AI-assisted setup¶
You can use this prompt with an AI assistant to automatically detect your project’s architecture and generate an appropriate eagle_eye_config.json.
Any problems you are facing, any suggestions you want to add, please feel free to reach us out.