Looking for data classes? Check out the freezed package, it is more ergonomic and has a lot of fancy features.

Looking for has/is getters? Check out the has_is_getters package!

Hey there! If you're reading this and want data classes to become a language-level feature of Dart, consider giving this issue a thumbs up. 👍

In the meantime, this library generates immutable data classes for you based on simple mutable blueprint classes. Here's how to get started:

1. 📦 Add these packages to your dependencies:

dependencies: data_classes: ^3.0.0 dev_dependencies: build_runner: ^1.7.1 data_classes_generator: ^3.0.0

2. 🧬 Write a blueprint class. Let the name start with Mutable and annotate it with @GenerateDataClass() :

import 'package:data_classes/data_classes.dart'; part 'my_file.g.dart'; @GenerateDataClass() class MutableFruit { String name; @nullable String color; }

By default, attributes are considered non-nullable. If you want an attribute to be nullable, annotate it with @nullable .

3. 🏭 Run pub run build_runner build in the command line (or flutter pub run build_runner build , if you're using Flutter). The implementation based on your mutable class will automatically be generated.

copy & copyWith #

By default, a copy method will be generated that takes a mutating function:

var freshApple = const Fruit( name: 'apple', color: 'green', ); var banana = freshApple.copy((fruit) => fruit ..name = 'banana' ..color = 'yellow' );

Sometimes, you have classes that are guaranteed to only have non-nullable variables. For those, you can opt in to generate a copyWith method!

@GenerateDataClass(generateCopyWith = true) class MutableFruit { String name; String color; } var oldApple = freshApple.copyWith( color: 'brown', );

If you're wondering why all fields have to be non-nullable, here's a discussion about that.

value getters #

Sometimes, you have enum values as fields. In that case, you have the option to generate getters directly on the immutable class:

enum Color { red, yellow, green, brown } enum Shape { round, curved } @GenerateDataClass() class MutableFruit { @GenerateValueGetters(generateNegations = true) Color color; @GenerateValueGetters(usePrefix = true) Shape theShape; } var banana = Fruit(color: Color.yellow, theShape: Shape.curved); banana.isYellow; // true banana.isNotGreen; // true banana.isTheShapeRound; // false

full example #

Here's an example with all the features (except nullability, so copyWith works). To showcase prefixed type imports, the Color enum from above has been moved to a file named colors.dart .

import 'package:data_classes/data_classes.dart'; import 'colors.dart' as colors; part 'main.g.dart'; enum Shape { round, curved } /// A fruit with a doc comment. @GenerateDataClass(generateCopyWith: true) class MutableFruit { String name; /// The color of this fruit. @GenerateValueGetters(generateNegations: true) colors.Color color; @GenerateValueGetters(usePrefix: true) Shape shape; List<String> likedBy; }

And here's the generated code: