clean_arch_lint

Analyzer plugin for Flutter Clean Architecture. It inspects import and export directives (AST) and reports layer violations in the IDE and via dart analyze / flutter analyze.

Each diagnostic is its own rule (see lib/src/rules), so it can be enabled or disabled independently. All of them share the layer resolution in ArchitectureImportRule.


Objective

Keep this structure honest:

lib/
 ├─ core/
 ├─ domain/
 ├─ data/
 ├─ presentation/
 └─ screens/

lib/src/{layer}/ is also detected, and so is a feature-first layout, lib/features/<feature>/{layer}/ (or lib/src/features/<feature>/{layer}/). No extra configuration.

In a feature-first layout the feature name plays no part in the checks: imports between features follow the same layer rules as any other import, so features/cart/presentation may import features/product/domain but not features/product/data.

Monorepos with one package per layer are detected by the package name suffix: my_app_domain, my_app_data, my_app_presentation, my_app_core, my_app_screens (and my_app itself) form one project, so my_app_presentation importing package:my_app_data/... is reported. Packages of another project that just end in a layer name, such as firebase_core, are not layers. Enable the plugin in each package's analysis_options.yaml.


Layers

domain

Innermost layer. Other layers may import domain; domain imports only itself plus the pure Dart libraries (dart:core, dart:async, dart:collection, dart:convert, dart:math, dart:typed_data). Flutter, other dart: libraries (dart:ui, dart:io, dart:html, …), and third-party packages are reported. Third-party packages can be allowed with allow_third_party_packages_in_domain.

Contains: entities, usecases, contracts.

core

Shared application code with no business rule, usable by every layer except domain. Must not import screens or presentation.

Contains: utils, extensions, constants, shared services (logging, configuration).

data

Infrastructure. Must not import screens or presentation.

Contains: datasources, models / DTOs, mappers, repository implementations.

presentation

UI that is not a screen entrypoint. Must not import data.

Contains: widgets, pages, bloc / cubit, viewmodels.

screens

Screen-level UI. Must not import data.

Contains: screens / routes that compose presentation and domain.


Diagnostics

All of them are WARNING lint rules. Analyzer plugins disable lints until you turn them on.

export directives are checked like imports: re-exporting a forbidden library leaks it to every file that imports the exporting one.

Code Blocks
no_data_dependencies presentation or screens importing data
no_screens_dependencies data or core importing screens or presentation
domain_only_depends_on_itself domain importing anything outside domain, except pure Dart libraries

allow_third_party_packages_in_domain is an option, not a check; see Configuration.

core_no_flutter, core_no_data_or_presentation, data_no_presentation, presentation_no_data, and domain_only no longer exist as separate rules.


Installation

Requires Dart SDK >= 3.13 (use a Flutter release that ships Dart 3.13 or newer). This is an analysis_server_plugin, not custom_lint.

1) Enable the plugin

Published:

plugins:
  clean_arch_lint:
    version: ^3.1.0
    diagnostics:
      no_data_dependencies: true
      domain_only_depends_on_itself: true
      no_screens_dependencies: true

Local path (see example/analysis_options.yaml):

plugins:
  clean_arch_lint:
    path: ../clean_arch_lint
    diagnostics:
      no_data_dependencies: true
      domain_only_depends_on_itself: true
      no_screens_dependencies: true

Restart the Dart Analysis Server after changing the plugins section.

2) Run analysis

dart analyze
# or
flutter analyze

Run it from the package root (or pass single files). Analyzing a directory, such as dart analyze lib, silently skips analyzer plugins: only the built-in lints run. This is a Dart SDK limitation (dart-lang/sdk#62710).

Diagnostics also appear in VS Code / Android Studio while you type.


Configuration

Raise severity

plugins:
  clean_arch_lint:
    version: ^3.1.0
    diagnostics:
      no_data_dependencies: error
      domain_only_depends_on_itself: error
      no_screens_dependencies: error

Allow third-party packages in domain

By default domain_only_depends_on_itself reports every third-party package in domain. To allow them (equatable, fpdart, meta, …), enable allow_third_party_packages_in_domain:

plugins:
  clean_arch_lint:
    version: ^3.1.0
    diagnostics:
      domain_only_depends_on_itself: true
      allow_third_party_packages_in_domain: true

It never reports anything by itself; it only changes domain_only_depends_on_itself. Flutter SDK packages (flutter, flutter_test, …), dart:ui, dart:io and the project's other layers stay reported. The plugins section only accepts diagnostics, so the option is a diagnostic name.

Suppress one line or a file

// ignore: clean_arch_lint/no_data_dependencies
import 'package:my_app/data/models/product_model.dart';

// ignore_for_file: clean_arch_lint/domain_only_depends_on_itself

Examples

See example/ for a working feature split across all layers, with one intentional violation per layer (including a relative import), two violations suppressed with // ignore, and a naming convention that makes the layer of each class obvious from its suffix (ProductEntity, ProductModel, ProductRepositoryImpl, ProductPage, ...).

Allowed:

import 'package:my_app/domain/entities/product_entity.dart';
import 'package:my_app/core/utils/price_formatter_util.dart';

Forbidden (presentation → data):

import 'package:my_app/data/models/product_model.dart'; // no_data_dependencies

Forbidden (domain → Flutter):

import 'package:flutter/material.dart'; // domain_only_depends_on_itself

Dependency flow

Layer Must not import
domain anything outside domain (except pure Dart libraries)
core screens, presentation
data screens, presentation
presentation data
screens data

What this plugin does not do

  • Does not generate code
  • Does not auto-fix imports
  • Does not replace code review

Stack

  • Dart SDK >= 3.13
  • analysis_server_plugin
  • analyzer

No custom_lint, build_runner, or source_gen.

Libraries

clean_arch_lint
Analyzer plugin that enforces Flutter Clean Architecture layer boundaries.
main