Rules / Correctness / avoid-global-state

avoid-global-state

lint/correctness/avoid-global-state
recommended
Same as avoid-global-state · Dart Code Metrics

Disallow mutable global and static state.

Flags top-level variables and static fields that are mutable — anything not declared const or plain final, including late final, which can still be assigned once at an arbitrary point. Mutable global state is reachable and writable from anywhere, which makes data flow hard to trace, introduces initialization-order and concurrency hazards, and lets tests contaminate one another through leftover shared state. Prefer const or final declarations, and thread mutable state explicitly through constructors or parameters rather than hanging it off globals.

Invalid

example.dartdart
// Bad: mutable global state
var globalList = <String>[];
int requestCount = 0;
String? cachedValue;

Map<String, dynamic> config = {};

class Database {
  static var instance;
}

List<int> shared = [];

void incrementCounter() {
  requestCount++; // uses bad global
}

late final String lateGlobal;
var uninitializedGlobal;
Avoid mutable global state — use const or final declarations instead
1// Bad: mutable global state
2var globalList = <String>[];
Avoid mutable global state — use const or final declarations instead
2var globalList = <String>[];
3int requestCount = 0;
Avoid mutable global state — use const or final declarations instead
3int requestCount = 0;
4String? cachedValue;
Avoid mutable global state — use const or final declarations instead
5
6Map<String, dynamic> config = {};
Avoid mutable global state — use const or final declarations instead
8class Database {
9 static var instance;
Avoid mutable global state — use const or final declarations instead
11
12List<int> shared = [];
Avoid mutable global state — use const or final declarations instead
17
18late final String lateGlobal;
Avoid mutable global state — use const or final declarations instead
18late final String lateGlobal;
19var uninitializedGlobal;

Valid

example.dartdart
// Good: const or immutable state
const String appName = 'MyApp';
const int maxRetries = 3;
const List<String> allowedRoles = ['admin', 'user'];

final Map<String, dynamic> config = {'version': 1};

final Duration defaultTimeout = Duration(seconds: 30);

// Good: state inside a class
class DatabaseManager {
  static final DatabaseManager _instance = DatabaseManager._();

  factory DatabaseManager() => _instance;

  DatabaseManager._();
}

class Counter {
  int count = 0;

  void increment() {
    count++;
  }
}

// Good: function-local state
void processRequest() {
  final List<String> tempList = [];
  var count = 0;
  // local variables are OK
}

// OK: @memoized pattern
class Service {
  @memoized
  Future<String> fetchData() async {
    return 'data';
  }
}

How to configure

Set the severity of avoid-global-state in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "correctness": {
        "avoid-global-state": "error"
      }
    }
  }
}