Library imported through a deep relative path instead of a package URI

ID

dart.portability.always_use_package_imports

Severity

info

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Portability

Language

Dart

Description

Reports an import, export or re-export directive whose URI is a relative path climbing THREE OR MORE directories ('../../../shared/widgets/spinner.dart') rather than a package: or dart: URI. A same-directory or one-level relative import ('../models/user.dart', 'helpers/format.dart') is not reported: measured over 8 real Flutter applications it is ordinary intra-feature code and was 45% of this rule’s output, while the deep chains are the ones that break when a file moves.

Rationale

A relative URI is resolved against the importing file, so the same library ends up known to the analyzer under two different identities when it is reached relatively from one file and through a package: URI from another. Dart then treats the two as unrelated libraries: private members stop matching, static state is duplicated, and is checks against the same class fail. Relative paths also break the moment a file is moved, and they cannot be resolved at all by code generators and tools that see only the package URI space.

The following code illustrates the pattern detected by this rule:

// A path that climbs three or more directories is the fragile case this rule targets.
// FLAGGED: Library imported through a deep relative path instead of a package URI
import '../../../../core/theme/app_theme.dart';

Remediation

Rewrite the URI as a package: URI naming your own package and the path under lib, for example import 'package:myapp/models/user.dart';. Keep relative URIs only where they are required, such as part/part of links between a library and its parts, and files outside lib (test, tool, bin) that intentionally reference each other.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved