skip to content

In Dart and Flutter, what are the lints package's core and recommended sets and flutter_lints, and which does a new Flutter app include?

level: juniorimportance: should knowfreq 45%

answer

  1. two rule sets in one Dart package
  2. recommended builds on core
  3. flutter.yaml adds widget-specific rules
  4. dev dependency plus an include: line
  5. flutter create writes both for you

basics

~10 s

The lints package ships two Dart-team rule sets: core catches critical problems, and recommended includes core plus idiomatic-style rules. flutter_lints builds on recommended with Flutter rules, and flutter create includes package:flutter_lints/flutter.yaml.

solid answer

~40 s

`package:lints` is the Dart team's official lint configuration. `core.yaml` holds rules for issues likely to break code at run time or for consumers; pub.dev's package score partly depends on passing them. `recommended.yaml` starts with `include: package:lints/core.yaml` and adds rules that enforce one idiomatic style. `flutter_lints` publishes `flutter.yaml`, which includes `package:lints/recommended.yaml` and adds Flutter rules such as `avoid_print`, `use_build_context_synchronously` and `use_key_in_widget_constructors`. `flutter create` adds `flutter_lints` as a dev dependency and writes an `analysis_options.yaml` that includes `package:flutter_lints/flutter.yaml`. A pure Dart package runs `dart pub add --dev lints` and includes one of the two sets. A new major version of either package can add rules, so code that passed analysis can start reporting issues after an upgrade.

code

yaml · 13 lines
yaml
# analysis_options.yaml written by flutter create (trimmed)
include: package:flutter_lints/flutter.yaml

analyzer:
  exclude:
    - build/**
    - android/**
    - ios/**

linter:
  rules:
    # avoid_print: false
    # prefer_single_quotes: true

go deeper

for a junior

Recall the chain: core, then recommended which includes core, then flutter_lints which includes recommended. Know that flutter create adds flutter_lints and the include line for you.

for a middle

Explain that a rule set is just an included YAML file, that local settings override it, and name a few rules flutter.yaml adds such as use_build_context_synchronously.

for a senior

Show you treat a lints or flutter_lints major upgrade as a planned change: read the changelog, run analysis, fix or switch off new rules deliberately.

for a principal

Weigh a shared team rule set published as its own package against each app curating rules, balancing consistency with the cost of upgrading many repos at once.

## What a lint set is The Dart **analyzer** reads a file named `analysis_options.yaml` at the root of a package. One of the things that file can do is switch on **linter rules**: small checks that flag code which compiles but is likely to be wrong, hard to read, or out of line with Effective Dart. There are hundreds of rules, and many of them disagree with each other on purpose (for example `prefer_single_quotes` and `prefer_double_quotes`). Picking rules one by one is tedious, so the Dart and Flutter teams publish curated **rule sets** as ordinary pub packages. A rule set is just a YAML file that lists rules; your project pulls it in with the `include:` key. ## The two sets in package:lints The `lints` package contains two files: - **`package:lints/core.yaml`**: rules for critical issues that are likely to cause problems when code runs or is consumed by others. Examples include `avoid_empty_else`, `await_only_futures`, `empty_catches`, `hash_and_equals`, `no_duplicate_case_values` and `unrelated_type_equality_checks`. The dart.dev docs say all code should pass these, and pub.dev's package score is based in part on them. - **`package:lints/recommended.yaml`**: its first line is `include: package:lints/core.yaml`, so it is a **superset** of core. It adds rules that catch further problems and enforce a single idiomatic style, such as `prefer_final_fields`, `unnecessary_this`, `unnecessary_new` and `use_super_parameters`. The Dart team recommends it for all Dart code. ## flutter_lints on top For Flutter code the recommendation is **`flutter_lints`**, not `lints` directly. Its `flutter.yaml` begins with `include: package:lints/recommended.yaml` and adds rules that only make sense in a widget codebase: | Rule | What it flags | |---|---| | `avoid_print` | `print` calls left in app code | | `use_build_context_synchronously` | a `BuildContext` used across an `await` without a mounted check | | `use_key_in_widget_constructors` | public widget constructors without a `key` parameter | | `sized_box_for_whitespace` | a `Container` used only for spacing | | `sort_child_properties_last` | `child`/`children` not passed as the last argument | | `avoid_web_libraries_in_flutter` | web-only libraries imported in a Flutter package | So the chain is **core → recommended → flutter**, each file including the one before it. ## What a new project gets When you run `flutter create`, the app template: 1. adds `flutter_lints` to `dev_dependencies` in `pubspec.yaml` (the Flutter 3.47 template pins `^6.0.0`); 2. writes an `analysis_options.yaml` whose first real line is `include: package:flutter_lints/flutter.yaml`; 3. adds an `analyzer: exclude:` list for `build/**` and the platform folders it generated (`android/**`, `ios/**` and so on); 4. leaves an empty `linter: rules:` section with comments showing how to switch individual rules on or off. A pure Dart package or CLI does the equivalent by hand: ```yaml # pubspec.yaml: dart pub add --dev lints # analysis_options.yaml include: package:lints/recommended.yaml ``` ## Why the set is a dev dependency, and what upgrades do The rule set is only read by tooling (IDEs, `dart analyze`), never compiled into the app, so it belongs in `dev_dependencies`. Because it is a versioned package, **upgrading it can change your results**: a new release may add rules to core or recommended, or remove low-value ones. The dart.dev guide warns that code which previously passed analysis might start failing after a new `lints` version. Teams handle this by upgrading deliberately, fixing the new findings (often with `dart fix`), or switching an unwanted new rule off in their own options file. ## Common confusions - The sets do not change the **compiler**. A lint finding never stops `flutter run` or `dart compile`; it only shows up in analysis output. - Including a set is not the same as enabling every rule that exists. Most rules are opt-in and live in no set at all. - `recommended` is not a stricter version of `core` with raised severities; it is core **plus more rules**. - Your own `analysis_options.yaml` still wins. Anything you set locally overrides what the included file says. ## Choosing a set for each kind of package A repository often holds more than one kind of package, and each can include a different set: - **A Flutter app or Flutter plugin**: `package:flutter_lints/flutter.yaml`, as the template writes it. - **A pure Dart library shared by several apps**: `package:lints/recommended.yaml`, since widget rules do not apply and a lighter dev dependency is enough. - **A command-line tool or server written in Dart**: also `recommended`; `avoid_print` would be wrong there, because printing is the tool's job. - **A team with extra conventions**: a local file that includes one of the above and then adds rules, or a shared options file that every package includes by relative path. Whatever the choice, the set is the **starting point**, not the finished policy. Interviewers usually follow up by asking which rules you added and why.

  • Why would a team add rules on top of flutter_lints rather than only use it?
    flutter_lints is a baseline meant to suit most apps, so it leaves out opinionated or costly rules. Teams add ones that match their risks, such as `unawaited_futures` or `prefer_single_quotes`, under `linter: rules:` in their own `analysis_options.yaml`. The local file extends the included set rather than replacing it.
  • Does a Dart-only package in a Flutter repo need flutter_lints?
    No. A package that does not depend on Flutter can include `package:lints/recommended.yaml` from the `lints` package. flutter_lints adds rules about widgets and `BuildContext` that do not apply there, and it would add a dev dependency the package does not otherwise need.

saying these in an interview costs you the question

  • Believes recommended.yaml is a separate list you must combine with core by hand
  • Thinks lint sets make the compiler reject code that breaks a rule
  • Adds flutter_lints under dependencies instead of dev_dependencies
  • Assumes including a set turns on every lint rule that exists
  • Expects a lints upgrade never to produce new findings on unchanged code