Tired of waiting for build_runner to churn through your codebase?
genq cuts through the wait and generates data classes for your Dart projects in milliseconds, not minutes. ⚡️
Inspired by freezed, genq offers a familiar syntax for defining data classes, but with a focus on lightning-fast performance. No need to write copyWith, toString, or equals methods by hand - genq does it all for you.
Here's what genq brings to the table:
- Reduce Boilerplate: genq generates the boilerplate code for you, so you can focus on what matters.
- Speed Demon: Generate data classes in a flash, even for large projects.
- Simple and Familiar: Syntax similar to freezed, making it easy to learn and use.
build_runner + freezed 🐌 |
genq 🚀 |
---|---|
In this benchmark (located in ./benchmarks
), count is the number of files in the benchmark, containing 250 annotated classes each. So for example, count=1 means 250 classes, count=2 means 500 classes, and so on. For count 10, build_runner
and freezed
took around 46 seconds, while genq
took 0.11 seconds. This is a >400x speedup!
- Never trust a benchmark you didn't falsify yourself.
- genq is optimized to perform one task and one task only - data class generation, whereas build_runner is built to do a lot more. Take this into account when choosing between the two.
Install genq via brew using the following command:
brew install jankuss/genq/genq
Or download the latest release from the releases page.
dependencies:
# ... Other dependencies ...
genq: ^0.2.0
import 'package:genq/genq.dart';
part 'user.genq.dart';
@genq
class User with _$User {
factory User({
required String name,
required int age,
}) = _User;
}
Read more about defining your data classes here.
Run the genq command in your project directory, and you will have your desired data classes generated in no time:
genq
To define a data class, annotate a class with @genq
and provide a factory constructor. The factory constructor should have named parameters for all desired fields in the class. The factory constructor should also have a = _<ClassName>
redirecting constructor.
import 'package:genq/genq.dart'; // <- Import genq
part 'user.genq.dart'; // <- Add a part directive to the generated file
@genq // <- Annotate the class with @genq
class User with _$User { // <- Add the mixin _$<ClassName>
factory User({ // <- Define a factory constructor
required String name, // <- Define fields as named parameters
required int age,
}) = _User; // <- Redirecting constructor, _<ClassName>
}
The generated class will have the following methods:
copyWith
: Create a copy of the data class with modified fields.toString
: Generate a human-readable string representation of the data class.==
: Compare two data classes for equality.
genq uses its own subset parser of the dart language and generates code directly from the parsed AST. This allows genq to generate code much faster than build_runner, which uses the analyzer. Code generation is also done in parallel for each file, which further speeds up the process.
The subset parser is written for the specific structures of data classes as defined here. Thus, there may be parsing errors if the code does not follow the expected structure. While the parser is generally robust when encountering unparsable code, there may be cases where it fails to parse the code correctly. If you encounter such a case, please open an issue with the code that caused the error.
build_runner
is extensible & pluggable and can be used for a wide variety of tasks, whereasgenq
is focused on data class generation. Freezed for example leverages this to generate JSON Serialization code usingjson_serializable
.genq
is written in Go, so it does not neatly integrate with the Dart ecosystem.
- JSON Serialization/Deserialization
- Extensibility