- Status: Accepted
- Date: 2026-06-22
It is Flutter's pattern for splitting one plugin into separately-owned pieces so different teams can support different platforms independently:
- a frontend package — the public Dart API the app uses,
- a platform interface package — the contract every implementation must fulfill,
- one platform implementation package per platform (Android, iOS, web, desktop…), each wired up automatically by the Flutter tool.
Its payoff is scaling to many platforms and letting third parties add a new platform without touching the frontend.
The pattern's benefits do not apply to us, and the cost is high:
-
No multi-platform / multi-owner need. We target only Android and iOS, both built in-repo by one team. No web/desktop on the roadmap and no third-party implementers — so the indirection buys abstraction we never use.
-
High, breaking cost. Federating our five modules means ~10–15 new packages, method-channel plumbing moved behind interface classes, and a coordinated publish story — a breaking change to the just-published 1.0.0 packages.
-
Testability is achievable without it. The real driver behind the suggestion is Dart-layer unit tests, which we can get by mocking the method channels directly (tracked separately).
Decision: keep the single-package-per-module structure. Revisit only if a
web/desktop target, a third-party implementer, or a much larger channel
surface appears — at which point federate sfmc_core first.
Note: sfmc_marketingcloudsdk and sfmc_mobileappmessaging depend on
sfmc_core: ^1.0.0, so sfmc_core already acts as a shared contract. Evolve
it additively (add methods, don't rename/remove); a breaking change forces a
coordinated major bump across all dependents.