xlints 1.0.1 copy "xlints: ^1.0.1" to clipboard
xlints: ^1.0.1 copied to clipboard

Flutter performance linter that detects costly code patterns and provides actionable optimization guidance.

xlints #

xlints is a Flutter lint package focused on widget and logic performance.

Available Rules #

xlints_prefer_const_constructors

Detects widgets that can be const but are not marked const.

BAD:

Widget build(BuildContext context) {
  return Padding(
    padding: EdgeInsets.all(8),
    child: Icon(Icons.star),
  );
}

GOOD:

Widget build(BuildContext context) {
  return const Padding(
    padding: EdgeInsets.all(8),
    child: Icon(Icons.star),
  );
}
xlints_prefer_listview_builder

Detects long lists that should use .builder.

BAD:

ListView(
  children: List.generate(1000, (i) => Text('Item $i')),
)

GOOD:

ListView.builder(
  itemCount: 1000,
  itemBuilder: (_, i) => Text('Item $i'),
)
xlints_avoid_listview_with_children

Detects ListView/GridView(children: ...) usage that builds all items eagerly.

BAD:

GridView(
  children: List.generate(200, (i) => Card(child: Text('$i'))),
)

GOOD:

GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
  itemCount: 200,
  itemBuilder: (_, i) => Card(child: Text('$i')),
)
xlints_avoid_opacity_widget

Detects Opacity usage in cases where a cheaper alternative is preferred.

BAD:

Opacity(
  opacity: 0.5,
  child: Image.network(url),
)

GOOD:

AnimatedOpacity(
  opacity: 0.5,
  duration: const Duration(milliseconds: 200),
  child: Image.network(url),
)
xlints_avoid_padding_wrapping_margin_widget

Detects Padding wrapping a child that already uses margin.

BAD:

Padding(
  padding: const EdgeInsets.all(16),
  child: Container(
    margin: const EdgeInsets.all(8),
    child: const Text('Hello'),
  ),
)

GOOD:

Container(
  margin: const EdgeInsets.all(24),
  child: const Text('Hello'),
)
xlints_avoid_shrink_wrap_true

Detects shrinkWrap: true on list/grid widgets, which can increase layout cost.

BAD:

ListView(
  shrinkWrap: true,
  children: items.map((e) => Text(e)).toList(),
)

GOOD:

Expanded(
  child: ListView.builder(
    itemCount: items.length,
    itemBuilder: (_, i) => Text(items[i]),
  ),
)
xlints_avoid_intrinsic_widgets

Detects expensive IntrinsicHeight/IntrinsicWidth usage.

BAD:

IntrinsicHeight(
  child: Row(children: children),
)

GOOD:

SizedBox(
  height: 72,
  child: Row(children: children),
)
xlints_avoid_controller_in_build

Detects controller/node creation inside build().

BAD:

@override
Widget build(BuildContext context) {
  final controller = ScrollController();
  return ListView(controller: controller);
}

BAD:

@override
Widget build(BuildContext context) {
  final focusNode = FocusNode();
  return TextField(focusNode: focusNode);
}

GOOD:

class _MyState extends State<MyWidget> {
  late final ScrollController controller;

  @override
  void initState() {
    super.initState();
    controller = ScrollController();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(controller: controller);
  }
}
xlints_avoid_widget_operator_equals

Detects operator == override on Widget subclasses.

BAD:

class MyCard extends StatelessWidget {
  @override
  bool operator ==(Object other) => identical(this, other);

  @override
  int get hashCode => 0;

  @override
  Widget build(BuildContext context) => const SizedBox();
}

GOOD:

class MyCard extends StatelessWidget {
  const MyCard({super.key});

  @override
  Widget build(BuildContext context) => const SizedBox();
}
xlints_avoid_set_state_in_build

Detects setState() calls inside build().

BAD:

@override
Widget build(BuildContext context) {
  setState(() => counter++);
  return Text('$counter');
}

GOOD:

void _increment() {
  setState(() => counter++);
}
xlints_prefer_string_buffer

Detects string concatenation with + inside loops.

BAD:

var result = '';
for (var i = 0; i < 1000; i++) {
  result = result + values[i];
}

GOOD:

final buffer = StringBuffer();
for (var i = 0; i < 1000; i++) {
  buffer.write(values[i]);
}
final result = buffer.toString();

Prerequisites #

  • Flutter SDK available in your environment.
  • Dart SDK compatible with this package (sdk: ^3.10.4).

Installation #

Option A: from pub.dev #

Add this to dev_dependencies:

dev_dependencies:
  xlints: ^1.0.0

Run:

flutter pub get

Option B: from a local path (for local development) #

dev_dependencies:
  xlints:
    path: ../path-to-xlints

Run:

flutter pub get

Configure analysis_options.yaml #

Choose one option.

Use this if you do not already have a lint baseline:

include: package:xlints/analysis_options.yaml

This enables:

  • package:lints/recommended.yaml
  • plugin custom_lint

Option 2: plugin-only #

Use this if your project already includes another lint config (for example flutter_lints):

include: package:xlints/analysis_options_xlints.yaml

Notes:

  • You do not need to add custom_lint manually to pubspec.yaml.
  • You do not need to add analyzer.plugins manually if you include one of the files above.

Run Lints #

Run from your Flutter app root:

dart run custom_lint

Alternative:

flutter pub run custom_lint

To auto-apply available fixes:

dart run custom_lint --fix

IDE Integration #

  • Make sure analysis_options.yaml is configured correctly.
  • Reopen the project if warnings do not appear.
  • Use lightbulb Quick Fix for rules that provide fixes.

Rules With Quick Fix (Current) #

  • xlints_prefer_const_constructors: adds the const keyword.
  • xlints_avoid_padding_wrapping_margin_widget: removes the outer Padding.

Rule Configuration #

Disable specific rules:

include: package:xlints/analysis_options.yaml

custom_lint:
  rules:
    - xlints_prefer_const_constructors: false
    - xlints_avoid_opacity_widget: false

Example Usage #

An example project is available in example/.

Run:

cd example
dart run custom_lint

The example intentionally contains bad patterns to trigger all xlints rules.

Troubleshooting #

include_file_not_found for package:xlints/analysis_options.yaml #

Common causes:

  • flutter pub get has not been run.
  • xlints is not present in your dependency graph.
  • Incorrect local path dependency.

Checklist:

  1. Ensure pubspec.yaml includes xlints in dev_dependencies.
  2. Run flutter pub get again.
  3. Ensure the include line is exactly: include: package:xlints/analysis_options.yaml
  4. Run dart run custom_lint again.

Rules do not appear in IDE, but appear in CLI #

  1. Reload the IDE window or restart the analysis server.
  2. Make sure the opened project root contains analysis_options.yaml.

Internal Dependencies #

  • analyzer: ^6.0.0
  • custom_lint: ^0.6.0
  • custom_lint_builder: ^0.6.0
3
likes
0
points
226
downloads

Publisher

verified publisheranonimeact.com

Weekly Downloads

Flutter performance linter that detects costly code patterns and provides actionable optimization guidance.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

analyzer, custom_lint, custom_lint_builder

More

Packages that depend on xlints