Dart macros · code generation on every save

copyWith, equality, JSON.
Generated on save.

Annotate a Dart class and save it. dmx writes the members into the class itself—no part directive, no .g.dart file, no build_runner run. Built-ins cover the usual jobs; Mustache templates and custom Dart macros cover the rest.

  • Automatic on save
  • No generated part files
  • Fully customizable
profile.dart watching
1@dmx('model', {'equality': false, 'toString': false})
2class Profile {
3  const Profile({required this.id});
4
5  final String id;
6
7  //#region
8  static Result<Profile, DecodeError> fromJson(Object? json, [String path = 'Profile']) =>
9      switch (json) {
10        {
11          'id': final String id,
12        } =>
13          Ok(Profile(
14            id: id,
15          )),
16        _ => Err(DecodeError(path, 'Profile', json)),
17      };
18
19  Map<String, dynamic> toJson() => <String, dynamic>{
20        'id': id,
21      };
22
23  Profile copyWith({
24    String? id,
25  }) =>
26      Profile(
27        id: id ?? this.id,
28      );
29  //#endregion
30}
Updates on save
Validated Dart

Generated by

built-insMustache templatesyour own Dart macros

Runs on save · checks Dart before writing

No command to run.
No .g.dart to open.

Dart uses identity equality by default, and Flutter recommends code generation for larger JSON models. dmx handles that boilerplate without dictating your model shape.

01

Watcher

Regenerates when you save.

The VS Code extension starts the watcher when your workspace opens. Saving a file whose generated output changed rewrites it; every other file is left alone.

Saveprofile.dart · generated members updated
Skiptheme.dart · generated output unchanged
02

Validated writes

It never writes broken Dart.

dmx parses the whole candidate file before writing. If generation fails, your file is left exactly as it was.

03

One complete file

No generated part files.

No .g.dart fragment, no generated mixin, no delegating factory. The members sit in the class, between two //#region markers.

Built-ins · templates · your own macros

Eleven macros ready.
Or write your own.

The built-ins cover models, unions, enums, routes, REST clients, and SQL tables. A Mustache template changes what they emit. A Dart macro generates something they do not cover.

D

Your Dart macro

Dart code that walks the parsed class — its fields, types and annotations — and returns the Dart to emit.

DB

SQLite example

A project macro reads a live database and writes one row class per table or view.

Every macro takes the same path

Six steps.
Every save.

Built-ins, your templates and your Dart macros all run through the same validation and atomic write. Macros that emit a whole file can be committed, or gitignored and rebuilt.

Build a custom Dart macro
  1. 01
    Watchsaved Dart files
  2. 02
    Inspecttyped declarations + project data
  3. 03
    Generatebuilt-in, template, or Dart macro
  4. 04
    Validatecomplete candidate Dart
  5. 05
    Writeinline or complete file
  6. 06
    Repeatautomatically on the next save

No install · no upload

Run it in your browser.
Nothing to install.

Edit Dart and the Mustache template, and see what dmx emits. The generator runs in the tab as WebAssembly, so neither input is uploaded.