---
data:
  title: "Using drift classes in other builders"
  description: Configure your build to allow drift dataclasses to be seen by other builders.
template: layouts/docs/single
---

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]({{ 'modular.md' | pageUrl }}). 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 `pubspec.yaml`:

```yaml
targets:
  drift:
    auto_apply_builders: false
    builders:
      drift_dev:analyzer:
        enabled: true
        options: &options
          # Drift build options, as per https://drift.simonbinder.eu/docs/advanced-features/builder_options/
          store_date_time_values_as_text: true
          named_parameters: true
          sql:
            dialect: sqlite
            options:
              version: "3.39"
              modules: [fts5]
      drift_dev:modular:
        enabled: true
        # We use yaml anchors to give the two builders the same options
        options: *options

  $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](https://github.com/simolus3/drift/tree/develop/examples/with_built_value).

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 `drift`
and `built_value` in the same project, those part files could be called `.drift.part` and `.built_value.part`.
Later, the common `source_gen` package would merge the part files into a single `.g.dart` file.

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|not_shared` and `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.

## Using `drift_dev:not_shared`

For complex build setups like those requiring other builders to see drift code, the `drift_dev:modular`
builder is recommended.
However, enabling the modular builder requires other code modifications like replacing `part` statements
with imports. A simpler change may be the `not_shared` builder offered by `drift_dev`. It works like the
default setup, except that it emits a `.drift.dart` part file instead of a shared `.g.dart` file - so you
only have to change a single `part` statement to migrate.

To enable this builder, also enable the `drift_dev:analyzer` builder and the `has_separate_analyzer`
option:

```yaml
targets:
  drift:
    auto_apply_builders: false
    builders:
      drift_dev:analyzer:
        enabled: true
        options: &options
          has_separate_analyzer: true # always enable this option when using `not_shared`
          # remaining options...
      drift_dev:not_shared:
        enabled: true
        # We use yaml anchors to give the two builders the same options
        options: *options

  $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
```
