Skip to content

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.
  • filePattern matches against the full file path relative to lib/. 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, or exclusiveDependencies. EagleEye also rejects empty or invalid filePattern values 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.