Macro Kit
A blazingly fast code generation tool for Dart that generates code instantly on saveβno build runner required.
β¨ Features
- β‘ Lightning Fast: Code generation in under 100ms after initial run
- πΎ Instant Generation: Press Ctrl+S and watch your code appear immediately
- π Easy Debugging: Debug your macros or third-party packages in real-time to understand and fix generation issues
- π« No Build Runner: Eliminate slow build processes and generated file conflicts
- π― Flexible & Capable: Handles most day-to-day code generation needs with macros
- π Live Development: Changes take effect instantlyβno separate build step needed
π¦ Installation
1. Activate the macro tool globally
dart pub global activate macro_kit
Or install from source:
dart pub global activate --source path ./
if you updating, just deactivate first and activate again.
2. Add macro_kit to your project
# pubspec.yaml
dependencies:
macro_kit: ^latest_version
3. Configure the analyzer plugin
# analysis_options.yaml
analyzer:
plugins:
- macro_kit
4. Initialize macros in your app
Add this to your main entry point. It only runs in development and has zero impact on production builds:
void main() async {
await runMacro(
macros: {
'DataClassMacro': DataClassMacro.initialize,
'AssetPathMacro': AssetPathMacro.initialize,
// Add your own macros or import from packages
},
);
runApp(MyApp());
}
π Quick Start
1. Annotate your class
import 'package:macro_kit/macro_kit.dart';
@dataClassMacro
class User with UserData {
const User({
required this.id,
required this.name,
required this.email,
});
final int id;
final String name;
final String email;
}
2. Save and generate
Press Ctrl+S to save. Generation happens instantly!
- First run: ~3-5 seconds (one-time setup)
- Subsequent runs: <100ms β‘
3. Use the generated code
The macro automatically generates:
- β
fromJson(Map<String, dynamic> json)constructor - β
toJson()method - β
Equality operators (
==,hashCode) - β
copyWith()method - β
toString()method
// Use it immediately
final User user = UserData.fromJson({'id': 1, 'name': 'Alice', 'email': 'alice@example.com'});
final json = user.toJson();
final updated = user.copyWith(name: 'Bob');
4. Debug when needed
Unlike build_runner, you can debug macro code generation in real-time. Run your app in debug mode and step through the generation process to identify and fix issues.
π Built-in Macros
DataClassMacro
Generates data class boilerplate including fromJson, toJson, copyWith, equality operators, and
toString.
@dataClassMacro
class UserProfile with UserProfileData {
const UserProfile({required this.name, required this.age});
final String name;
final int age;
}
AssetPathMacro
Generates type-safe constants for your asset paths. Never hardcode asset strings again!
void main() async {
await runMacro(
macros: {
'DataClassMacro': DataClassMacro.initialize,
'AssetPathMacro': AssetPathMacro.initialize,
// Add your own macros or import from packages
},
assetMacros: {
'assets': [
AssetMacroInfo(
macroName: 'AssetPathMacro',
extension: '*',
output: 'lib',
),
],
},
);
runApp(MyApp());
}
// Usage in code
final asset = Image.asset(AssetPaths.logo);
final asset = Image.asset(AssetPaths.icons.home);
π― Why Macro Kit?
| Feature | Macro Kit | build_runner |
|---|---|---|
| Generation Speed | <100ms | Seconds to minutes |
| Debugging | β Full debug support | β Limited |
| File Conflicts | β Never | β Common issue |
| IDE Integration | β Instant feedback | β³ Wait for build |
| Learning Curve | π’ Simple | π΄ Complex |
π§ Running Macros Separately
You can create a dedicated macro runner file to keep your macro setup separate from your app's main entry point.
For mobile apps, itβs recommended to use a separate macro-runner file to isolate your macro setup from the main entry point. This remains the preferred workflow until macros are fully supported on physical Android and iOS devices
Create a macro runner
Create a new file macro.dart in your project root or lib directory:
// macro.dart
import 'package:macro_kit/macro_kit.dart';
void main() async {
await runMacro(
macros: {
'DataClassMacro': DataClassMacro.initialize,
'AssetPathMacro': AssetPathMacro.initialize,
// Add your own macros or import from packages
},
assetMacros: {
'assets': [
AssetMacroInfo(
macroName: 'AssetPathMacro',
extension: '*',
output: 'lib',
),
],
},
);
}
Run from CLI
dart run macro.dart
Run from IDE
Simply open macro.dart in your IDE and run it directly using the run button or keyboard shortcut.
β οΈ Current Limitations
Macros can currently only be applied to classes. This covers most common use cases, but future updates will include:
- π Support for applying macros to variables and functions
- π Additional macro capabilities for library developers
- π More built-in macros for common patterns
Despite these limitations, Macro Kit handles the majority of day-to-day code generation needs efficiently.
π€ Contributing
Contributions are welcome! Feel free to:
- π Report bugs and issues
- π‘ Suggest new features
- π§ Submit pull requests
π License
MIT License - see LICENSE for details