Repository navigation
[flutter_tools] support build-time plugins #112727
Description
Activity
- addedtoolAffects the "flutter" command-line tool. See also t: labels.Affects the "flutter" command-line tool. See also t: labels.c: proposalA detailed proposal for a change to FlutterA detailed proposal for a change to Flutter
on Sep 30, 2022 And proposes they present themselves as plugins.
I'm not sure what this means; Flutter plugins are Dart packages that include native code that's built into the application. What you are proposing doesn't have that, so they aren't Flutter plugins. (They are also tool-install-level, not project-level, which is also a critical difference.) What does "present themselves as plugins" actually mean?
(As I said in the other issue, I really think it would be helpful to pick a different term to use for this proposal. Using the same word for a totally unrelated concept as what we currently use it for within Flutter seems needlessly confusing to me. There are other terms, like "extension", that don't have the same established meaning within the Flutter domain.)
Yea I'm open to alternative names. What I meant and what is important is:
- They are available on pub.dev
- They can be added in a
pubspec.yamlas adev_dependencyof any flutter module.
It sounds like you meant "presents as a package" then.
Reacted by gaaclarke- changed the title
[-]Design a plugin interface for tool[/-][+]Design a plugin interface for `tool`[/+]on Sep 30, 2022 @stuartmorgan as per our discussion the other day I think you make a convincing argument against making it easier to support any language with runtime costs. I've added it a non-goal to the description. When the design in more detailed we can consider if it is something worth actively blocking (ex blocking libraries with the symbols to fork or create threads?).
cc @jonasfj on our idea of having Rust as a
build_dependency:for Dart standalone packages that want to use the rust compiler in a build step.Ability to generate native libraries in the cache
@jonasfj and I have been debating whether native tools (downloaded or locally built) should live in pub cache or in the
.dart_toolof the root package.Which native artifact you end up with, could depend on package resolution. And a native-tool-package might get a different downloaded/built artifact if one if its dependencies gets resolved to a different version. However, this means the rust compiler would be downloaded for every project it is transitively used, which is undesirable.
The alternative is that we mandate that native tools should not depend on any of the dependencies that their enclosing package lists. Then the rust compiler can live in the pub cache. (We would still get multiple versions of the rust_compiler package in the cache over time, so we probably also need to think about purging the pub cache.)
on our idea of having Rust as a build_dependency: for Dart standalone packages that want to use the rust compiler in a build step.
@dcharkes Is Dart planning on adding
build_dependencies? Are you using Rust as the example to decide how that will work wrt caching artifacts?So, one thing I learned while doing my projects in Rust is that some packages have options that determine how they operate. For example, the sdl2 package has a
featurethat allows you to determine if the library for sdl2 is "bundled" or not. If you set it to true, it will download (and build?) the appropriate library for you into the cache, otherwise it will be up to you to provide the binary for sdl2. If we had a similar mechanism we could specify if we wanted to use the rustc on "$PATH" or download it.For what it's worth, here's how it would look in a Rust package:
[dependencies.sdl2] version = "0.35" features = ["bundled"]
Reacted by Daco HarkesBy happenstance I was playing around with Rust this weekend and I saw that they've already implemented a similar feature to this for their package manager. Here's some notes about what they are doing:
Cargo (Rust's package manager) has 3 classes of dependencies:
dependencies,dev-dependencies,build-dependencies. The first 2 classes operate like Dart's, but the 3rd class ,build-dependencies, don't exist in Dart and add packages that can modify the build process ( documentation ).Here is an example
build-dependenciescrate that does code generation for binding Rust and C++:cxx-build. It is a direct comparison to our Pigeon use-case.Also, related to the idea that a package could add command-line arguments to the
fluttertool, Cargo has that ability too. Here is a package that adds a new command to Cargo, cargo-llvm-cov. In fact, all commands thatcargoimplements appear to be packages. The equivalent for Flutter would be if thefluttertool was modular and ever command (flutter build,flutter run, etc) was its own module.- addedteam-toolOwned by Flutter Tool teamOwned by Flutter Tool team
on Jul 8, 2023 - addedP3Issues that are less important to the Flutter projectIssues that are less important to the Flutter projecttriaged-toolTriaged by Flutter Tool teamTriaged by Flutter Tool team
on Jul 18, 2023 - changed the title
[-]Design a plugin interface for `tool`[/-][+][flutter_tools] support build-time plugins[/+]on Jul 21, 2023 I expect this feature too.
This feature means that developers can combine more actions with flutter build process such as changing version number before building.
Reacted by gaaclarke, Carlos Gutiérrez Moreno and ph3rinAnother use case for this is the flutter engine team would like to have tools for engine development that we don't want to introduce to the mainline tool. For example, a command-line flag for forcing opengles rendering in impeller.
We don't plan to support something like this, though the upcoming Dart native assets/builders might help.
We don't plan to support something like this
@matanlurey The reason why we don't plan to support it is important to resolving this issue. If we don't have the bandwidth to support it, as an open source product I think it's valuable to still document the proposal and continue to be a place to guide discussion on it. We are potentially one customer away from having this feature. Closing the issue will cause the discussion to be locked.
If we don't think the proposal has value, I would argue we know it does because the feature exists in other ecosystems and there are good concrete examples of it. If we think the proposal is antithetical to Flutter's design, it would be important to document that for design iteration or guiding future proposals.
though the upcoming Dart native assets/builders might help
Neither of those solve the needs listed in the description. I think builders could be part of the solution if it was better integrated into the flutter tooling.
Right, but the tools team isn't doing it, and it isn't prioritized elsewhere. Keeping this issue open indefinitely so that we continue to not do it is not helpful.
Right, but the tools team isn't doing it, and it isn't prioritized elsewhere. Keeping this issue open indefinitely so that we continue to not do it is not helpful.
Since this is an open source product, I would think having open issues that the core team isn't addressing is actually helpful. Contributors can't easily work on things that are actively being addressed. We can chat about it as a team at the next sync to figure out what's most helpful in this case.
We wouldn't accept a contributor proposal for this, it's a large complicated feature.
The use cases are described somewhat sparsely, so I'm not sure if I fully grasp them and the things we're working on would cover them.
1. Pigeon - The code generator for Flutter interop. Right now you have to use it externally to generate the code, this could be integrated as a build-time plugin.
We are considering adding a generic way to run code generators in Dart. Tracking bug:
2. Rust language support for plugins - This could install extra project templates and when executing build it can look for the presence of "rustc" and execute rust compilation, generating a library that can be linked in during the rest of the compilation.
The build hooks system enables bundling and bundling Rust libraries. Tracking bug:
However, we do not have a Rust (or C) plugin interface for Flutter, so you cannot interact with the Flutter Plugin API.
They can be added in a
pubspec.yamlas adev_dependencyof any flutter module.Code generators can be dev dependencies provided the generated code is checked in.
Code that produces binaries that are bundled/linked in the final application should not be dev dependencies. Assuming you have Dart code which interacts with your native code, you'd want to avoid version skew between the two.
Is Dart planning on adding
build_dependencies?Right now we're using normal dependencies to avoid version skew. However, if we have conflicting version constraints between a build-time dependency and a run-time dependency, we might want to go this direction. Tracking bug:
If any of your use cases are covered by the above mentioned tracking bugs, please document your use case in the relevant bug.
Reacted by gaaclarke@dcharkes what do you mean by "Code generators can be dev dependencies provided the generated code is checked in."?
The idea is that if a project wanted to to have pigeon code generation it would add a
dev_dependencyon pigeon. The generated code wouldn't necessarily need to be checked in since it can be regenerated.@dcharkes what do you mean by "Code generators can be dev dependencies provided the generated code is checked in."?
The idea is that if a project wanted to to have pigeon code generation it would add a
dev_dependencyon pigeon. The generated code wouldn't necessarily need to be checked in since it can be regenerated.It can only be a dev dependency if users of the package will never have to run code generation. Code generators might have external dependencies, and the generated code might not have those dependencies. (E.g. libclang to generate bindings for a dylib, but the generated code can just use
dart:ffito call functions.) So, the package developers need to run the code generators, and the package users don't.(An alternative design is to not check the code in. Then the dependencies must be normal dependencies or build dependencies. Otherwise the users of your package don't have the source of the generator after
pub get. But, I believe checking in generated code is a better workflow after our experience with FFIgen and JNIgen in the last couple of years.)@dcharkes, I think I see. In that case we need a
build_dependenciesinstead. Anydependenciesofbuild_dependencieseffectively becomes abuild_dependencies. I was hoping we could avoid the 3rd designation. I think this is the path that Rust took too.Reacted by Daco HarkesThis thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.- locked as resolved and limited conversation to collaborators
on Jul 28, 2025
Flutter has a defined interface for creating runtime plugins, we should also design a plugin interface that can be executed at build-time. These plugins would live on pub.dev and runtime plugins could have have dependencies on them.
We've talked about this in the past with respect to code generation. This proposal provides more generic hooks for Dart compilation or native compilation (linking in particular). And proposes they present themselves as packages in pub.dev.
Example Build-time plugins
Requirements
Bonus objectives
Non-goals