The fast linter for Dart & Flutter

falcon lints Dart and Flutter projects with 512 rules from a single Rust binary. It parses Dart itself, so it never boots the Dart analyzer, and it speaks LSP for your editor.

dart pub global activate falcon

falcon vs dart analyze Same rules, cold analyzer cache

falcon 0.4.6 · dart analyze 3.13.5 · mean wall-clock time per corpus; speedups vs dart analyze

4.4–5.5× faster than dart analyze on 4 corpora

  1. cfug/dio5.2× fasterfalcon270 msdart analyze1.39 s
  2. felangel/bloc4.4× fasterfalcon114 msdart analyze502 ms
  3. flame-engine/flame4.5× fasterfalcon3.56 sdart analyze16.1 s
  4. three flutter/packages plugin families5.5× fasterfalcon4.10 sdart analyze22.7 s
  • Same rules, warm analyzer cache: dart analyze was faster on cfug/dio, felangel/bloc and flame-engine/flame; falcon was faster on three flutter/packages plugin families (2.5×).
  • DCL rules, cold analyzer cache: falcon 7.8–41× faster than Dart Code Linter on 3 corpora; no comparison on three flutter/packages plugin families: Dart Code Linter not measured (DCL 4.4.4 drops nested package contexts under a single root (analyzer_utils.dart getFilePaths); multiple roots analyze 259 files twice).
  • DCL rules, warm analyzer cache: falcon 4.3–23× faster than Dart Code Linter on 3 corpora; no comparison on three flutter/packages plugin families: Dart Code Linter not measured (DCL 4.4.4 drops nested package contexts under a single root (analyzer_utils.dart getFilePaths); multiple roots analyze 259 files twice).
  • Each scenario enables matching rule names within its rule family. Matching names do not imply identical work or diagnostic output. When measured, dart analyze also type-checks; falcon does not.
All 16 runs and methodology

Real diagnostics, pinned to the line

This is falcon's actual output for avoid-function-literals-in-foreach-calls, taken from the rule's test fixture. Every rule page shows the same: the code that triggers it, the exact message, and the fix.

  • One falcon.json, rules grouped by intent
  • Inline suppressions that must state a reason
  • falcon migrate reads your analysis_options.yaml
  • Text or JSON output for CI, and LSP for your editor
example.dart5 diagnostics
void bad(List<int> items, List<int> list, List<int> names, List<int> values,    List<int> data, void Function(int) save, void Function(int) sink,    void Function(int) process, void Function(int) log) {  items.forEach((e) { print(e); });avoid-function-literals-in-foreach-calls Avoid using a function literal in a `forEach` call; use a for-in loop instead.  list.forEach((x) => print(x));  names.forEach((name) { save(name); });  values.forEach((v) => sink(v));  data.forEach((item) { process(item); log(item); });}

512 rules, sorted by what they catch

215 rules implement official Dart lints and keep their analyzer names, so falcon migrate can carry your analysis_options.yaml over. The rest come from Dart Code Metrics, Pyramid Lint, and falcon itself.

  1. Accessibility4
  2. Complexity47
  3. Correctness144
  4. Performance26
  5. Security5
  6. Style233
  7. Suspicious53

Framework domains

Where the rules come from

Falcon
224
Dart lints
215
Dart Code Metrics
42
Pyramid Lint
31

Coming from dart analyze, DCM, or custom_lint?

falcon runs beside the analyzer, not inside it, so it adds no plugin to your analysis server. Same rules, cold analyzer cache: falcon 4.4–5.5× faster than dart analyze on 4 corpora. Every rule is free and MIT licensed.

Compare falcon with other Dart linters

Install

terminalbash
# Linux and macOS; needs Dart's pub cache bin directory on PATH
dart pub global activate falcon

falcon check .
All platforms and editor extensions