v0.4.3Dart 3.10+Apache-2.0
Dead code detector for Dart and Flutter.
Finds declarations nothing references and removes them for you. One command, no setup, backed by the Dart analysis server.
“Ciach!” /tɕax/ — Polish for the sound of a clean chop.
dart pub global activate ciach
$ ciach
lib/greeting.dart
15:6 function danglingFunction (public)
24:7 variable unusedConstant (public)
lib/orphans.dart
8:7 class UnusedClass (public)
22:7 class FullyDeadClass (public)
31:3 constructor ReferencedAsTypeOnly.new (public)
Found 5 unused declarations in 2 files (scanned 13 files, 44 declarations, 0.5s).
--remove
Report it. Or ciach it.
One flag deletes what was found, doc comments included, after showing the list and asking first.
/// Referenced from bin/app.dart.
void registerHandlers() {
_internalHelper();
}
void _internalHelper() {}
/// Nothing calls this any more.
void danglingFunction() {}
const usedConstant = 'hello';
/// Left behind after a refactor.
const unusedConstant = 'bye';
class UnusedClass {
void orphanMethod() {}
}
$ ciach --remove
lib/greeting.dart
9:6 function danglingFunction (public)
14:7 variable unusedConstant (public)
16:7 class UnusedClass (public)
17:8 method UnusedClass.orphanMethod (public)
Found 4 unused declarations in 1 file (scanned 1 file, 8 declarations, 0.4s).
Remove 4 unused declarations? [y/N] y
Removed 4 unused declarations from 1 file.
Features
Sharp, and careful about it.
-
Every declaration kind
Classes, enums and their values, functions, methods, constructors, fields, getters, variables and more.
-
Backed by the real analyzer
Reference queries go to the Dart analysis server: the same resolution your IDE uses, not a regex.
-
Built for CI
Annotations inline on the pull request diff and a non-zero exit when anything turns up.
-
Safe defaults
@overridemembers, operators, entry points, generated files andtoJson()are skipped unless you opt in. -
Text, JSON or GitHub output
Human-readable by default, machine-readable on request.
-
A config file, optionally
Every flag can live in
ciach.yaml. The command line always wins.
Output
Speaks human, machine and GitHub.
Pick the format with -f. Exit codes are the same in every one.
lib/orphans.dart
8:7 class UnusedClass (public)
10:8 method UnusedClass.orphanMethod (public)
22:7 class FullyDeadClass (public)
31:3 constructor ReferencedAsTypeOnly.new (public)
Found 4 unused declarations in 1 file (scanned 1 file, 6 declarations, 0.7s).
{
"summary": {
"filesScanned": 1,
"declarationsChecked": 6,
"unusedCount": 4,
"docOnlyCount": 0,
"elapsedMs": 729
},
"unused": [
{
"name": "UnusedClass",
"qualifiedName": "UnusedClass",
"kind": "class",
"file": "lib/orphans.dart",
"line": 8,
"column": 7,
"isPrivate": false
}
],
"docOnly": []
}
::warning file=lib/orphans.dart,line=8,col=7,title=Unused declaration::Unused class 'UnusedClass'
::warning file=lib/orphans.dart,line=10,col=8,title=Unused declaration::Unused method 'UnusedClass.orphanMethod'
::warning file=lib/orphans.dart,line=22,col=7,title=Unused declaration::Unused class 'FullyDeadClass'
::notice file=lib/greeting.dart,line=41,col=6,title=Referenced only from a doc comment::function '_docOnlyMentioned' has no code references, only a dartdoc link