all_observer_lint 0.4.0
all_observer_lint: ^0.4.0 copied to clipboard
Official lint rules and automated fixes for safe, predictable, and efficient development with all_observer.
all_observer_lint #
[all_observer_lint banner]
Official lint rules for building safer Flutter and Dart apps with
all_observer.
Leia em português
all_observer_lint helps catch common reactive mistakes directly in your IDE:
state created inside build, effects registered on every rebuild, invalid
watch(context) usage, impure Computed callbacks, and reactive resources that
were not disposed.
It is a development-only package. It does not change your app runtime.
Install #
Add both packages as development dependencies:
dart pub add --dev custom_lint all_observer_lint
For Flutter projects:
flutter pub add --dev custom_lint all_observer_lint
Your pubspec.yaml should contain:
dev_dependencies:
custom_lint: ^0.8.0
all_observer_lint: ^0.4.0
custom_lint is required because it is the analyzer runner that loads custom
lint plugins. all_observer_lint provides the rules.
Configure #
In analysis_options.yaml, use the recommended preset:
include: package:all_observer_lint/recommended.yaml
That preset enables the custom_lint analyzer plugin and the recommended rule
set.
To show diagnostics in Brazilian Portuguese:
include: package:all_observer_lint/recommended.yaml
custom_lint:
rules:
- all_observer:
language: pt-BR
Migrating from 0.3.x #
The package installation command did not change, but custom options now use
the custom_lint.rules configuration shape. If you previously configured
Portuguese diagnostics with a top-level all_observer: key, move that option
under custom_lint.rules as shown above.
Run #
Use your normal analyzer workflow:
dart analyze
Or run the custom lint runner directly:
dart run custom_lint
In Flutter projects:
flutter analyze
dart run custom_lint
Most IDEs show the diagnostics automatically after pub get.
Example #
This code creates reactive state every time the widget rebuilds:
Widget build(BuildContext context) {
final count = 0.obs;
return Text('${count.value}');
}
all_observer_lint reports:
warning: Avoid creating reactive state inside build. The resource will be
recreated whenever the widget rebuilds. Move it to a State field, initState,
controller, view model, or another lifecycle-managed object.
Move the state to a lifecycle-managed place:
class _CounterPageState extends State<CounterPage> {
final count = 0.obs;
@override
Widget build(BuildContext context) {
return Observer(() => Text('${count.value}'));
}
}
Quick Fixes #
Some rules provide IDE quick fixes. For example, dispose_reactive_resources
can add a missing dispose() call:
class _SearchPageState extends State<SearchPage> {
late final worker = debounce(query, onSearch);
@override
void dispose() {
worker.dispose();
super.dispose();
}
}
Presets #
| Preset | Use when |
|---|---|
recommended.yaml |
You want the default rule set for everyday projects. |
strict.yaml |
You also want experimental suggestions for cleaner reactive design. |
all.yaml |
You want to try every available rule. |
Rules #
| Rule | What it catches |
|---|---|
avoid_reactive_creation_in_build |
Observable, .obs, Computed, ObservableFuture, or ObservableStream created inside rebuild scopes. |
avoid_effect_creation_in_build |
effect, ever, once, debounce, or interval registered inside rebuild scopes. |
watch_only_inside_build |
watch(context) used outside widget build contexts. |
dispose_reactive_resources |
Workers/effects/streams stored in fields but not disposed. |
avoid_reactive_write_in_computed |
Reactive writes inside Computed callbacks. |
avoid_set_state_in_computed |
setState inside Computed callbacks. |
avoid_worker_creation_in_computed |
Workers/effects created inside Computed callbacks. |
avoid_io_in_computed |
await or obvious dart:io work inside Computed callbacks. |
avoid_observable_write_during_observer_build |
Reactive writes while an Observer is building. |
self_referencing_computed |
A Computed value directly reading its own .value. |
prefer_computed_for_derived_state |
Manual derived state that could be a Computed. |
prefer_batch_for_multiple_related_writes |
Related reactive writes that may benefit from batch. |
prefer_assign_all_for_reactive_list_replace |
ObservableList.clear() followed by add/addAll; prefer assign/assignAll. |
unused_reactive_state |
Private reactive fields or top-level variables that are never used in the same file. |
unobserved_reactive_read_in_build |
Reactive .value reads rendered in build without Observer or watch(context). |
More Documentation #
- Example app
- Architecture and why
custom_lintis required - Known limitations and future rules
- False positive policy
License #
MIT. See LICENSE.