dcq_dead_code 0.3.0 copy "dcq_dead_code: ^0.3.0" to clipboard
dcq_dead_code: ^0.3.0 copied to clipboard

Dead code analysis for Dart packages and mono-repos.

dcq_dead_code #

pub package License: BSD-3

Dead code analysis for Dart leaf packages and monorepos. Finds unused declarations, nearly-unused symbols, and dependency usage across one or more packages.

Features #

  • Dead code detection -- finds public and private declarations with no external references.
  • Entry-point reachability -- DFS walk from main() and @pragma('vm:entry-point') preserves transitively referenced code.
  • Monorepo support -- analyze multiple packages together so cross-package references are tracked correctly.
  • Nearly-unused symbols -- surfaces symbols with very few external references (configurable threshold).
  • Dependency usage -- aggregates how many symbols are used from each dependency.
  • Smart filtering -- excludes generated files (.g.dart, .freezed.dart, etc.), test/example directories, and override methods.

Usage #

This package is the analysis library behind the dead-code subcommand in the dcq CLI. For installation and CLI usage, see the dcq_standalone README.

You can also use it directly as a library if you really want:

import 'package:dcq_dead_code/dcq_dead_code.dart';

// Discover packages (returns a record with nullable list + error)
final (packageDirs, error) = discoverPackageDirs(['.']);
if (packageDirs == null) throw Exception(error);

// Find unused declarations
final deadCode = await analyzeDeadCode(packageDirs: packageDirs);

for (final decl in deadCode) {
  print('${decl.filePath}:${decl.line} - unused ${decl.kind.name} "${decl.name}"');
}

// Full analysis (dead code + nearly-unused + dependency usage)
final result = await analyzeAll(packageDirs: packageDirs);
formatDeadCodeText(result.deadDeclarations).forEach(print);
formatNearlyUnusedText(result.nearlyUnusedSymbols).forEach(print);
formatDependencyUsageText(result.dependencyUsage).forEach(print);

Leaf packages and accurate results #

The tool determines whether code is "dead" by checking if it is referenced from outside its defining library within the analyzed set. This means it works best on leaf packages -- packages with no downstream dependents, such as applications or CLIs that define main().

If you analyze a library package on its own, its entire public API will appear dead because no consumer is present in the analysis. To get accurate results for library packages, include their known consumers in the same analysis:

dcq dead-code packages/my_lib packages/my_app
# Or also just:
dcq dead-code packages

In a monorepo, pass the repo root or all package directories so that cross-package references are tracked together:

dcq dead-code .

[Dead Code Diagram]

How it works #

  1. Package discovery -- expands input paths into concrete package directories by scanning for pubspec.yaml files.
  2. Declaration collection -- walks each resolved CompilationUnit and records all top-level and member declarations with stable element IDs (<library_uri>:<name>@<offset>).
  3. Reference collection -- tracks which libraries reference each element, including synthetic getters/setters and inferred types.
  4. Entry-point reachability -- starting from entry points, performs a DFS through the same-library reference graph to mark transitively reachable code as alive.
  5. Filtering -- removes overrides, generated files, and test/example directories. Public symbols with only internal references are flagged as candidates for privatization rather than removal.
1
likes
160
points
147
downloads

Documentation

API reference

Publisher

verified publishercarson.lol

Weekly Downloads

Dead code analysis for Dart packages and mono-repos.

Repository (GitHub)
View/report issues

Topics

#dead-code #analysis #code-quality

License

BSD-3-Clause (license)

Dependencies

analyzer, path

More

Packages that depend on dcq_dead_code