Using drift classes in other builders
It is possible to use classes generated by drift in other builders. Due to technicalities related to Dart's build system and
source_gen, this approach requires a custom build configuration. For complex builds like this, we recommend running drift in it's modular mode. This more is more efficient for larger builds and can be enabled by putting this content in a file called
build.yaml next to your
targets: drift: auto_apply_builders: false builders: drift_dev:modular: enabled: true $default: dependencies: # run drift's builder first - ":drift" builders: # This builder is enabled by default, but we're using the modular builder in # its own target instead. drift_dev: enabled: false
With modular generation, you'll have to replace the
part statement in the database file with an import to
filename.drift.dart. Also, your database class now extends from
$DatabaseName, without a leading underscore.
By generating independent libraries, drift can manage imports on its own. By declaring a dependency in
build.yaml, the build system also ensures that drift-generated files are ready before
built_value or other builders that need to see them are running.
A full example is available as part of the drift repo.
If you run into any problems with this approach, feel free to open an issue on drift.
The technicalities, explained
Almost all code generation packages use a so called "shared part file" approach provided by
source_gen. It's a common protocol that allows unrelated builders to write into the same
.g.dart file. For this to work, each builder first writes a
.part file with its name. For instance, if you used
built_value in the same project, those part files could be called
.built_value.part. Later, the common
source_gen package would merge the part files into a single
This works great for most use cases, but a downside is that each builder can't see the final
.g.dart file, or use any classes or methods defined in it. To fix that, drift offers other builders -
drift_dev|modular - those will generate a separate file only containing code generated by drift. So most of the work resolves around disabling the default generator of drift and use the non-shared generator instead.
Finally, we need to the build system to run drift first, and all the other builders otherwise. This is why we split the builders up into multiple targets. The first target will only run drift, the second target has a dependency on the first one and will run all the other builders.