[Short] Flutter : Let’s talk about lint rules

Quentin Klein
La Mobilery
Published in
5 min readMay 17, 2024
Lint Rullllllllles

Recently I talked with a guy on LinkedIn, who’s name is Nicolas.
Nicolas has made some videos on youtube where he talks about dev.

Like this one (in French).

This video talks (among other things) about prettier.

If you are familiar with the web dev, you know prettier, if not, it is a tool that helps formatting your code well using some rules.

And there is a sentence in that video I liked a lot, I’m gonna rephrase it

In a project (in your IDE), you are like home, it is running like you want, everything is at the place it should be… for you.

How about when others join ? They eat in your bathroom, leave some toilet paper in the fridge when they are drunk and all sort of crazy stuff (yeah maybe my friends are weird).

My point is, when you are alone, in your home. It is your rules. But when you are a team (more than 1), then it is not your home, it is a flat-share.

And a flat-share needs common rules, like this one.

Dart Lint

Flutter is a framework, the language is Dart. You know that (because this article would be less interesting if you don’t).

First of all note that dart has an official recommended rules list

That being said, Flutter does not use it and has its own https://github.com/flutter/flutter/blob/master/analysis_options.yaml

When you create a Dart (Flutter) project, you can see a file called analysis_options.yaml

This file contains the rules of the flat-share. But by default, this file does not contains much.

include: package:flutter_lints/flutter.yaml

But the included file contains more

# Recommended lints for Flutter apps, packages, and plugins.

include: package:lints/recommended.yaml

linter:
rules:
- avoid_print
- avoid_unnecessary_containers
- avoid_web_libraries_in_flutter
- no_logic_in_create_state
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- sized_box_for_whitespace
- sort_child_properties_last
- use_build_context_synchronously
- use_full_hex_values_for_flutter_colors
- use_key_in_widget_constructors

And so on with the included included package that I will not paste here

Those rules are fine, but they are rules that have been decided above you. Its is more like guidelines

What should you use ?

Flame, a popular game engine has its own file https://github.com/flame-engine/flame/blob/main/packages/flame_lint/lib/analysis_options.yaml

Why not you ?

In the real world, when you share the rent, you share the rules.

It means in my opinion, every single team that works on a flutter or a dart project should take time to go through the list of rules available and pick if they want it or not.

Democracy ! (Helldivers 2)

Build your own analysis_options.yaml !

How to do so, the full list of available lints is here https://dart.dev/tools/linter-rules/all

Most of them are detailed here https://dart.dev/tools/linter-rules

Some of them has a `has fix` label, this is great because the linter will have an option to fix the issue for you.

You even can create a custom one if you want using the invertase package custom_lint.

What do I use ?

At La Mobilery, with the Flutter team, we took half a day to check the rules. Here what came out of it.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

analyzer:
exclude:
— “build/**”
— “**/*.g.dart”
— “**/*.gen.dart”
— “**/*.freezed.dart”

linter:
rules:
avoid_redundant_argument_values: true
avoid_init_to_null: true
avoid_print: true
control_flow_in_finally: true
constant_identifier_names: true
curly_braces_in_flow_control_structures: true
exhaustive_cases: true
file_names: true
library_prefixes: true
non_constant_identifier_names: true
null_check_on_nullable_type_parameter: true
prefer_const_constructors: true
prefer_contains: true
prefer_final_fields: true
prefer_is_empty: true
prefer_null_aware_operators: true
sized_box_for_whitespace: true
slash_for_doc_comments: true
unnecessary_brace_in_string_interps: true
unnecessary_constructor_name: true
unnecessary_late: true
unnecessary_parenthesis: true
unnecessary_string_escapes: true
unnecessary_string_interpolations: true
always_use_package_imports: true
depend_on_referenced_packages: true
prefer_single_quotes: true
require_trailing_commas: true
always_put_required_named_parameters_first: false
sort_pub_dependencies: false
prefer_if_elements_to_conditional_expressions: false

strong-mode:
implicit-casts: false
implicit-dynamic: false

And don’t forget those we DO NOT want

Strong mode is well explained here

Bonus

If you are using VSCode, please note that you can run the fixes at save :)
It will fix all the fixable detected lints for you ! Time saving like hell.

To do so, edit the User settings.json and add this

"editor.codeActionsOnSave": {
"source.organizeImports": "explicit",
"source.fixAll": "explicit",
"quickfix.create.constructorForFinalFields": "explicit"
},
"[dart]": {
"editor.formatOnSave": true,
"editor.formatOnType": true,
}

So, I hope you will enjoy taking time with the folks you code with. No more time doing bullshit review in pull request that said, you forgot the , here ! What a time to be alive.

If you enjoyed this, please share it, and share your rules in comments, it is always a pleasure to discuss them.

You can also follow me on LinkedIn for more articles like this one

https://www.linkedin.com/in/quentin-klein/

--

--