Unified Flutter plugins for the Salesforce Marketing Cloud SDK — a Melos workspace monorepo that wraps the native Android and iOS libraries behind a single, modular Dart surface using Flutter's platform channels.
Historically, integrating Marketing Cloud features into a Flutter app required a single monolithic plugin covering the entire SDK surface. This monorepo splits the functionality into focused packages — pick the product package you need and add only the optional feature packages (push, iam) you actually use.
| Package | Description |
|---|---|
sfmc_core |
Foundation: identity, custom attributes, structured events, logging |
sfmc_push |
Push registration & notifications |
sfmc_iam |
In-App Messaging lifecycle events, display control & programmatic display |
sfmc_marketingcloudsdk |
MarketingCloud Engagement: inbox, tags, attributes, analytics, registration, location & proximity |
sfmc_mobileappmessaging |
MobileAppMessaging: analytics, registration |
sfmc_marketingcloudsdk and sfmc_mobileappmessaging are product packages — each transitively depends on sfmc_core, so adding a product package resolves the foundation module automatically. sfmc_push and sfmc_iam are independent, opt-in feature packages: add them explicitly to your pubspec.yaml if you need push or in-app messaging.
- Flutter >=3.3.0 with Dart >=3.0.6.
- Melos workspace — each package is independently versioned and publishable; the example app consumes packages via path dependencies.
requestSdk()pattern — every package exposes a staticrequestSdk()that lazily initializes the native SDK. Subsequent calls are no-ops.- Event streams — modules expose Dart
Streams viaEventChannelfor streaming events (push token refresh, registration changes, inbox updates). - Platform channels — each package registers its own
MethodChannel(sfmc/sfmc_core,sfmc/push,sfmc/iam,sfmc/marketingcloudsdk,sfmc/mobileappmessaging).
packages/
├── sfmc_core/ # foundation: identity, events, logging
├── sfmc_push/ # push tokens & enable/disable
├── sfmc_iam/ # in-app messaging
├── sfmc_marketingcloudsdk/ # product: engagement (depends on core)
└── sfmc_mobileappmessaging/ # product: MAM (depends on core)
example/ # Flutter demo app (Android + iOS)
flutter pub add sfmc_marketingcloudsdk
# or
flutter pub add sfmc_mobileappmessaging
# add the optional feature packages you need
flutter pub add sfmc_push
flutter pub add sfmc_iamInstalling a product package (
sfmc_marketingcloudsdkorsfmc_mobileappmessaging) auto-resolvessfmc_core.sfmc_pushandsfmc_iamare opt-in — add them explicitly if you need push or in-app messaging.
- Add the Marketing Cloud SDK Maven repository to your project-level
android/build.gradle:allprojects { repositories { maven { url "https://salesforce-marketingcloud.github.io/MarketingCloudSDK-Android/repository" } } } - Provide Firebase Cloud Messaging credentials — place your
google-services.jsoninandroid/app/and apply the Google Services plugin. - Provide a Firebase BOM. The Marketing Cloud SDK declares
firebase-messagingwithout a version, expecting the consuming app to pin one via a BOM. Add it to your app and inject it into the SFMC plugin subprojects:See// android/app/build.gradle dependencies { implementation platform("com.google.firebase:firebase-bom:33.0.0") implementation "com.google.firebase:firebase-messaging" } // android/build.gradle (project-level) subprojects { sub -> if (sub.name.startsWith('sfmc_')) { sub.afterEvaluate { sub.dependencies { implementation platform("com.google.firebase:firebase-bom:33.0.0") } } } }
example/android/for a working reference (the BOM version is centralized ingradle.properties). - Configure the SDK in your
MainApplication.ktusing the multi-moduleConfigBuilderpattern. See Initialize the SDK.
For full setup instructions, see the Android SDK Integration Guide.
- Run
flutter pub getfrom the project root first — this generates.flutter-pluginsand.flutter-plugins-dependencieswhich CocoaPods needs to resolve plugin symlinks. - Install CocoaPods dependencies — run
cd ios && pod install. - Configure APNs — set up an Authentication Key (
.p8) or Certificate (.p12) in your Apple Developer account and upload to MobilePush Administration. - Configure the SDK in your
AppDelegate.swiftusing the multi-moduleConfigBuilderpattern. See Configure the SDK. If you are starting from theexample/ios/Runner/AppDelegate.swifttemplate, replace theYOUR_*placeholder credentials (appID,accessToken,appEndpointURL,mid, and the MAM equivalents) with your Marketing Cloud values before running the app. - Enable push notifications in Xcode: Push Notifications and Background Modes (Remote Notifications) capabilities.
For full setup instructions, see the iOS SDK Integration Guide.
import 'package:sfmc_core/sfmc_core.dart';
import 'package:sfmc_marketingcloudsdk/sfmc_marketingcloudsdk.dart';
// Initialize core
await SFMCSdkModule.requestSdk();
await SFMCSdkModule.setProfileId('user-123');
await SFMCSdkModule.setAttribute('plan', 'pro');
await SFMCSdkModule.track(
CustomEvent(name: 'purchase', attributes: {'amount': '49.99'}),
);
// Use the engagement product
await MarketingCloudSdk.requestSdk();
final unread = await MarketingCloudSdk.getUnreadMessages();
if (unread.isNotEmpty) {
await MarketingCloudSdk.markMessageRead(unread[0].id!);
}See each package's README for full API documentation with links to native SDK docs.
Architecture decisions for this monorepo are recorded as ADRs under
docs/decisions/:
- ADR 0001: Federated plugin design — why we keep a single package per module instead of adopting Flutter's federated plugin pattern.
| Platform | Minimum |
|---|---|
| Flutter | 3.3.0 |
| Dart SDK | >=3.0.6 <4.0.0 |
| iOS | 12.0+ |
| Android | minSdk 26, compileSdk 36 |
| Android Artifact | Version |
|---|---|
| sfmcsdk | 3.1.+ |
| marketingcloudsdk | 11.0.+ |
| pushfeaturemodule | 2.0.+ |
| inappmessagingfeaturemodule | 1.0.+ |
| mobileappmessagingsdk | 1.1.+ |
| iOS Pod | Version |
|---|---|
| MarketingCloud-SFMCSdk | ~> 4.0.0 |
| MarketingCloudSDK | ~> 11.0.0 |
| SFPushFeatureSDK | ~> 2.0.0 |
| SFInAppMessagingFeatureSDK | ~> 1.0.0 |
| SFMobileAppMessagingSDK | ~> 2.0.0 |
Where possible, we changed noninclusive terms to align with our company value of Equality. We retained noninclusive terms to document a third-party system, but we encourage the developer community to embrace more inclusive language. We can update the term when it's no longer required for technical accuracy.
BSD 3-Clause.