During my participation in FlutterConfLatam, I had the privilege of discussing one of Dart’s most promising new features: macros. Still in its experimental phase, this tool has the potential to transform how we write and generate code in Dart. In this blog article, I’ll break down the essentials of macros, their functionality, and how they can significantly improve the developer experience. If you're curious, feel free to explore my talk on YouTube and review the reference code in the FlutterConfLatam Demo repository.
What are Macros in Dart?
According to the official documentation:
“A macro in Dart is a user-definable piece of code that takes other code as input and operates on it in real time to create, modify, or add declarations.”
Source: dart.dev
In simple terms, macros empower developers to write code that generates additional code. This simplifies repetitive tasks, reducing dependency on external tools. To better understand their potential, let’s examine a common use case and how macros provide a more efficient solution.
Practical use case: JSON Serialization
One of the most common scenarios in Flutter applications is working with APIs that return JSON responses. Traditionally, developers rely on libraries like json_serializable combined with build_runner to generate the necessary code for serializing and deserializing JSON. Here’s a typical workflow:
- Define the User class with specific annotations.
- Add dependencies (json_serializable, build_runner, json_annotation).
Run the command:
- This generates implementations for fromJson and toJson methods.
Here’s what the code might look like:
After running the command, user.g.dart is generated with methods like:
While functional, this approach has its drawbacks:
- Dependency on external commands.
- Generated files clutter the repository.
- Difficulty integrating real-time changes.
Streamlining the Process with Dart Macros
Dart introduces the json package, featuring a macro called JsonCodable. This eliminates the need for tools like build_runner and simplifies the process.
Configuration
In your pubspec.yaml, add:
Then, define your User class with:
By annotating with @JsonCodable(), Dart’s macro generates fromJson and toJson methods in real-time without requiring additional commands.
Generated Code
The macro-generated code exists in memory within Dart’s VM and is visible through tools like VS Code:
Key benefits of Dart Macros
- Fewer External Dependencies: Removes reliance on build_runner and json_serializable.
- Clean Codebase: No additional files cluttering your repository.
- Real-Time Updates: Changes in the base class reflect immediately in the generated code.
- Enhanced Development Experience: Debugging tools allow inspection without manual edits.
How Macros work: A deeper explanation
Macros in Dart are implemented in packages, allowing for distribution and reuse. They operate in three progressive phases:
- Types phase
- Goal: Declare new types and establish top-level names.
- Capabilities: Limited introspection ensures compatibility with existing types.
- Declarations phase
- Goal: Define members, variables, and methods.
- Capabilities: Inspect type hierarchies to add meaningful functionality.
- Definitions phase
- Goal: Generate the executable code for declared methods.
- Capabilities: Full introspection ensures accurate code generation.
Execution order
Macros follow an “inner-first, outer-last” execution order to ensure consistency:
In this case, First executes before Second, maintaining predictable behavior.
Dart’s macros represent a monumental step forward in how we write and manage code. By reducing repetitive tasks, minimizing dependencies, and enabling real-time updates, macros streamline development workflows and elevate the overall coding experience.
As we anticipate their official release in 2025, now is the perfect time to experiment and consider migrating your codebase. At Somnio Software, we’re excited about the potential of macros and their transformative impact on Flutter development.
Explore the future of Flutter development with us at Somnio Software—where innovation meets expertise.
We specialize in making the most out of cutting-edge technologies like Flutter to build powerful and scalable apps to help you reach your business goals!
Reach out to us today to learn how we can transform your dreams into reality.