leancode_lint 15.1.0 copy "leancode_lint: ^15.1.0" to clipboard
leancode_lint: ^15.1.0 copied to clipboard

Robust, high-quality lint rules used at LeanCode.

leancode_lint #

leancode_lint pub.dev badge

An opinionated set of high-quality, robust, and up-to-date lint rules used at LeanCode.

Installation #

  1. Add leancode_lint and custom_lint as a dev dependency in your project's pubspec.yaml.

    dart pub add leancode_lint custom_lint --dev
    
    copied to clipboard
  2. In your analysis_options.yaml add include: package:leancode_lint/analysis_options.yaml. You might want to exclude some files (e.g generated json serializable) from analysis.

  3. Enable the custom_lint analyzer plugin in analysis_options.yaml. You can customize lint rules by adding a custom_lint config with a rules section.

  4. Run flutter pub get in your project main directory and restart your IDE. You're ready to go!

Example analysis_options.yaml:

include: package:leancode_lint/analysis_options.yaml

# Optional lint rules configuration
custom_lint:
  rules:
    - use_design_system_item:
      AppText:
        - instead_of: Text
          from_package: flutter
        - instead_of: RichText
          from_package: flutter
      AppScaffold:
        - instead_of: Scaffold
          from_package: flutter

analyzer:
  plugins:
    # Required for our custom lints support
    - custom_lint
  exclude:
    - '**/*.g.dart'
copied to clipboard

Usage in libraries #

If your package is a library rather than a binary application, you will expose some public API for users of your library. Therefore, you should use lint rules optimized for this case by just changing your include entry in analysis_options.yaml:

include: package:leancode_lint/analysis_options_package.yaml
copied to clipboard

Custom lint rules #

To disable a particular custom lint rule, set the rule to false in analysis_options.yaml. For example, to disable prefix_widgets_returning_slivers:

custom_lint:
  rules:
    - prefix_widgets_returning_slivers: false
copied to clipboard

add_cubit_suffix_for_your_cubits #

DO add a 'Cubit' suffix to your cubit names.

BAD:

class MyClass extends Cubit<int> {}
copied to clipboard

GOOD:

class MyClassCubit extends Cubit<int> {}
copied to clipboard

Configuration

None.

avoid_conditional_hooks #

AVOID using hooks conditionally

BAD:

Widget build(BuildContext context) {
  if (condition) {
    useEffect(() {
      // ...
    }, []);
  }
}
copied to clipboard

BAD:

Widget build(BuildContext context) {
  final controller = this.controller ?? useTextEditingController();
}
copied to clipboard

BAD:

Widget build(BuildContext context) {
  if (condition) {
    return Text('Early return');
  }

  final state = useState(0);
}
copied to clipboard

GOOD:

Widget build(BuildContext context) {
  useEffect(() {
    if (condition) {
        // ...
    }
  }, []);
}
copied to clipboard

GOOD:

Widget build(BuildContext context) {
  final backingController = useTextEditingController();
  final controller = this.controller ?? backingController;
}
copied to clipboard

GOOD:

Widget build(BuildContext context) {
  final state = useState(0);

  if (condition) {
    return Text('Early return');
  }
}
copied to clipboard

Configuration

None.

catch_parameter_names #

DO name catch clause parameters consistently

  • if it's a catch-all, the exception should be named err and the stacktrace st
  • if it's a typed catch, the stacktrace has to be named st

BAD:

try {} catch (e, s) {}
try {} on SocketException catch (e, s) {}
copied to clipboard

GOOD:

try {} catch (err, st) {}
try {} on SocketException catch (e, st) {}
copied to clipboard

Configuration

None.

hook_widget_does_not_use_hooks #

AVOID extending HookWidget if no hooks are used.

BAD:

class MyWidget extends HookWidget {
  @override
  Widget build(BuildContext context) {
    return Placeholder();
  }
}
copied to clipboard

BAD:

HookBuilder(
  builder: (context) {
    return Placeholder();
  },
);
copied to clipboard

GOOD:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Placeholder();
  }
}
copied to clipboard

GOOD:

Builder(
  builder: (context) {
    return Placeholder();
  },
);
copied to clipboard

Configuration

None.

prefix_widgets_returning_slivers #

DO prefix widget names with 'Sliver' if the widget returns slivers.

BAD:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SliverToBoxAdapter();
  }
}
copied to clipboard

GOOD:

class SliverMyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SliverToBoxAdapter();
  }
}
copied to clipboard

Configuration

  • application_prefix: A string. Specifies the application prefix to accept sliver prefixes. For example if set to "Lncd" then "LncdSliverMyWidget" is a valid sliver name.
custom_lint:
  rules:
    - prefix_widgets_returning_slivers:
      application_prefix: Lncd
copied to clipboard

start_comments_with_space #

DO start comments/docs with an empty space.

BAD:

//some comment
///some doc
copied to clipboard

GOOD:

// some comment
/// some doc
copied to clipboard

Configuration

None.

use_design_system_item #

AVOID using items disallowed by the design system.

This rule has to be configured to do anything. The rule will highlight forbidden usages and suggest alternatives preferred by the design system.

Configuration

  • <preferredItem>: The item to be preferred. A list of objects:
    • instead_of: A required string. Name of the item that is forbidden.
    • from_package: A required string. Name of the package from which that forbidden item is from.
custom_lint:
  rules:
    - use_design_system_item:
      LncdText:
        - instead_of: Text
          from_package: flutter
        - instead_of: RichText
          from_package: flutter
      LncdScaffold:
        - instead_of: Scaffold
          from_package: flutter
copied to clipboard

avoid_single_child_in_multi_child_widgets #

AVOID using Column, Row, Flex, Wrap, SliverList, MultiSliver, SliverChildListDelegate, SliverMainAxisGroup, and SliverCrossAxisGroup with a single child.

BAD:

Column(
  children: [
    Container(),
  ]
)
copied to clipboard

GOOD:

Container(),
copied to clipboard

Configuration

None.

Assists #

Assists are IDE refactorings not related to a particular issue. They can be triggered by placing your cursor over a relevant piece of code and opening the code actions dialog. For instance, in VSCode this is done with ctrl+. or +..

See linked source code containing explanation in dart doc.

65
likes
120
points
16.2k
downloads

Publisher

verified publisherleancode.co

Weekly Downloads

2024.09.22 - 2025.04.06

Robust, high-quality lint rules used at LeanCode.

Homepage
Repository (GitHub)

Topics

#analysis #lints

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

analyzer, analyzer_plugin, custom_lint_builder

More

Packages that depend on leancode_lint