In a Flutter federated plugin, how does endorsing a platform package with default_package work, and how does an app use a non-endorsed implementation instead?
answer
- app-facing pubspec lists the endorsement
- default_package plus a real dependency
- direct dependency of the app wins
- one candidate is used without question
- ambiguity fails the build
basics
~20 sThe app-facing package endorses a platform package by depending on it and naming it as default_package for that platform, so apps get it automatically. An app picks a non-endorsed implementation by adding it as a direct dependency, which the Flutter tool prefers.
solid answer
~40 sEndorsement lives in the **app-facing** pubspec: under `flutter: plugin: platforms:` a platform entry says `default_package: thermo_windows`, and `thermo_windows` also appears in `dependencies:` so it is actually resolved. Apps that depend on `thermo` then get the Windows implementation transitively. When the Flutter tool resolves implementations per platform it uses, in order: the only candidate if there is one; otherwise a **direct dependency of the app**; otherwise the endorsed `default_package`; otherwise it stops with a "multiple possible implementations" error. So to use a non-endorsed `thermo_windows_alt`, you add it to your app's `dependencies:` — the same move also overrides an endorsed implementation. Two conflicting direct implementations are an error.
go deeper
Remember that endorsed implementations come automatically with the app-facing package, while non-endorsed ones are added to your own pubspec.
Explain default_package plus the matching dependency in the app-facing pubspec, and the resolution order: single candidate, direct dependency, default, then an error.
Diagnose multiple-implementation and conflicting-dependency build errors and choose when overriding an endorsed implementation is worth owning its compatibility.
Set a policy for accepting outside platform packages as endorsed, since each endorsement ties the app-facing release cycle to another maintainer.
## Endorsed versus non-endorsed In a package-separated federated plugin, a platform package can be: - **Endorsed** — the author of the app-facing package has agreed to include it. Apps that depend on the app-facing package get it automatically. - **Non-endorsed** — anyone else's implementation of the same interface. It works, but an app must add it to its own `pubspec.yaml` explicitly. The documentation's advice is to coordinate with the app-facing author so an implementation becomes endorsed; the non-endorsed path exists for when that is not possible, and for overriding an endorsed choice. ## How endorsement is written Two things in the **app-facing** package's pubspec, both required: ```yaml flutter: plugin: platforms: android: package: com.example.thermo pluginClass: ThermoPlugin ios: pluginClass: ThermoPlugin web: default_package: thermo_web dependencies: thermo_web: ^1.0.0 ``` 1. A platform entry whose only key is `default_package`, naming the implementing package. 2. A normal dependency on that package, so version solving actually brings it into the app. If the dependency is missing, the tool cannot find the named package and prints a warning that it "does not exist, or is not a plugin package". The endorsed package itself declares `implements: thermo` and an inline implementation for that platform. Note the mix above: Android and iOS are implemented **inline** in `thermo`, while the web is delegated. The tool rejects two combinations for the same platform: an inline `pluginClass`/`dartPluginClass` together with `default_package`, and `implements:` together with `default_package`. ## How the Flutter tool picks one implementation For each platform and each app-facing plugin, `flutter_tools` gathers every package that implements it, then resolves: | Step | Rule | Outcome | |---|---|---| | 1 | Exactly one candidate | Use it | | 2 | One candidate is a **direct dependency** of the app | Use it | | 2b | Several direct candidates | Error: "conflicting direct dependency implementations" — unless one is the app-facing package with its inline code and one is a single implementing package, in which case the implementing package wins | | 3 | The app-facing package's `default_package` is among the candidates | Use it | | 4 | Still several candidates | Error: "multiple possible implementations… add one of these dependencies to pubspec.yaml" | ## Using a non-endorsed implementation Because a direct dependency outranks the default, the app simply lists both: ```yaml dependencies: thermo: ^1.0.0 thermo_windows: ^1.0.0 # non-endorsed implementation ``` The same trick **overrides** an endorsed implementation: add your preferred implementing package directly and it beats `default_package`. ## Practical consequences - Endorsing is a release of the app-facing package: adding or swapping `default_package` means publishing a new app-facing version. - An app that pins a non-endorsed implementation now owns its compatibility with the interface version the app-facing package expects. - When two transitive packages both implement the same plugin and none is endorsed or direct, the build stops rather than guessing; the fix is to add one of them directly. - Endorsement is about **default selection**, not about code review or a trust mark on pub.dev. ## Common confusions - `default_package` does not go in the implementing package's pubspec — that one uses `implements:`. - Listing a package under `default_package` without depending on it does not endorse anything that works; it only produces a warning. - A non-endorsed implementation does not need the app-facing author's permission; it needs only to extend the published interface.
- Why must the app-facing package also list the endorsed package under dependencies?`default_package` only names a preference; version solving decides what is actually in the app. Without the dependency the endorsed package is never resolved, so the tool warns that the default does not exist and apps get no implementation for that platform.
- Two transitive dependencies both implement the same plugin for Windows and neither is endorsed. What does the build do, and how do you fix it?The Flutter tool refuses to guess and reports that the plugin has multiple possible implementations for that platform. Adding the one you want as a direct dependency of the app resolves it, because direct dependencies win over other candidates.
saying these in an interview costs you the question
- Endorsement is a verified-publisher badge granted on pub.dev.
- The implementing package declares default_package in its own pubspec.
- The tool picks whichever implementation happens to resolve first.
- Overriding an endorsed implementation requires forking the app-facing package.
- Naming default_package alone is enough; no dependency is needed.