Code Generation in Dart with build_runner

October 8, 2024 dart

Dart's code generation tooling is one of its killer features. Projects like json_serializable, freezed, and my own auto_mappr all use it to eliminate boilerplate.

How build_runner Works#

build_runner watches your source files and runs Builder classes against them. A builder reads an input file, transforms it, and writes an output file — typically with a .g.dart suffix.

dart run build_runner build
# or during development:
dart run build_runner watch

Writing a Simple Builder#

class MyBuilder implements Builder {
  @override
  Map<String, List<String>> get buildExtensions => {
    '.dart': ['.g.dart'],
  };

  @override
  Future<void> build(BuildStep buildStep) async {
    final inputId = buildStep.inputId;
    final outputId = inputId.changeExtension('.g.dart');
    await buildStep.writeAsString(outputId, '// generated');
  }
}

auto_mappr Under the Hood#

auto_mappr reads your @AutoMappr annotation, inspects the generic type arguments, and generates a complete mapping implementation — no runtime reflection needed.

The generated code is plain Dart that you can read and debug, which makes it much easier to trust than runtime magic.

More posts

All posts →