Skip to content

Compatibility matrix

Every row is a fact from admob-cmp/README.md and gradle/libs.versions.toml. The matrix is intentionally narrow: every 1.x release has been built with the same Kotlin and Compose Multiplatform versions, because the library was designed for stability across the 1.x line.

A note on rows that are not in the table. The library has not yet shipped a 2.0.0 release. When it does, the Kotlin floor will rise — the roadmap discusses the upstream gates that would force the rise. The 1.x line is expected to receive fixes for as long as the ecosystem lags the upstream conditions, which is the design that makes the Kotlin 2.3.20 floor safe to publish against.

admob-cmpKotlinCompose MultiplatformAndroid minSdkiOS deployment target
1.1.02.3.201.11.12615.0
1.0.22.3.201.11.12615.0
1.0.12.3.201.11.12615.0
1.0.02.3.201.11.12615.0
Ad formats
FormatAndroid — GMA Next-Gen, API 26+iOS — GMA 13.x, iOS 15+Notes
Banner Supported SupportedAnchored adaptive, inline adaptive, fixed and fluid; collapsible on both platforms
Interstitial Supported SupportedTTL'd FIFO cache, 1 hour
Rewarded Supported SupportedRewardEarned event
Rewarded interstitial Supported SupportedSame controller shape as Rewarded
App-open Supported SupportedAppOpenAdCoordinator, cooldowns, blocking; cache TTL 4 hours
Native Supported SupportedadLayout DSL and pooling on both; iOS renders through UIKit
Cross-cutting capabilities
CapabilityAndroidiOSNotes
UMP consent and privacy-options form Supported SupportedcanRequestAds gates every request on both platforms
App Tracking Transparency Not applicable SupportedAndroid has no ATT: adManager.tracking always reports AdTrackingAuthorization.NotApplicable, and the AD_ID manifest permission governs the advertising id there instead
Mediation adapters Supported SupportedNo adapters are bundled; add the ones you need
Paid and revenue events Supported SupportedAdEvent.Paid carries AdValue and response info
Native video events Not available Supported — five eventsiOS emits VideoStarted, VideoPlayed, VideoPaused, VideoEnded and VideoMuted through GADVideoControllerDelegate. The Android GMA Next-Gen SDK exposes no equivalent callback surface on NativeAd, so Android emits none. This is an upstream SDK gap, not an admob-cmp omission — do not rely on native video events for cross-platform logic.
immersiveMode, customClickGesture, publisherProvidedId, categoryExclusions, skipUninitializedAdapters Supported Silently ignoredAndroid-only request options
customTargeting, placementId Supported SupportedMapped on both platforms; placementId maps to placementID on iOS
Platform support matrix: six formats on Android and iOSCLAUDE.md invariants #11Read this diagram in words

Android and iOS are the supported ad targets, and a Kotlin Multiplatform project may target additional platforms — the ads API simply is not available in those source sets. The architecture reference explains why desktop and web are out of scope.

Which Kotlin version do I need, and why is it strict?

Section titled “Which Kotlin version do I need, and why is it strict?”

This section must not be softened.

The library is published as Kotlin/Native klibs plus cinterop klibs. Klibs are not binary-compatible across arbitrary Kotlin versions, so consumers must build with a compatible compiler. admob-cmp is compiled with Kotlin 2.3.20; consumers on a different Kotlin minor version may fail to resolve the klib. Patch versions are generally safe.

The two directions, explicitly. Consumers on an older Kotlin than the library are unsupported in every case. Consumers on a newer Kotlin are the supported direction for ordinary klibs but are unverified for the cinterop klibs.

A practical note on how to verify. The installation guide has the ./gradlew :shared:iosSimulatorArm64Test command that exercises the cinterop klib path end-to-end. If the link succeeds, the consumer’s Kotlin version resolves the klib. If it fails with undefined symbols related to GMA or UMP, the resolution is unsupported. The troubleshooting guide has the full symptom table; the conservative wording here is the policy that the symptom table is built on.

Compose Multiplatform is required only for the composable surface: BannerAdView, NativeAdView and rememberAdManager. The controller API — AdManager, the controllers, AdPlacement — has no Compose dependency. On Android outside Compose, AdMob.manager(context) returns the same process-wide singleton.

A practical note: a project that depends on admob-cmp-core directly (skipping admob-cmp-compose) still gets the controllers, the consent API, the diagnostics, and the event streams. It does not get BannerAdView, NativeAdView, or rememberAdManager, because those live in the compose surface. Most production code uses both; server-side tools and CLIs use only admob-cmp-core.

A related point: Compose Multiplatform itself requires a matching Kotlin version, and a project that uses Compose Multiplatform 1.11.1 is implicitly using Kotlin 2.3.20, because Compose Multiplatform pins its Kotlin version. The “Kotlin 2.3.20 only” floor is therefore a no-op for most projects that use the composable surface — the floor is already set by the Compose Multiplatform version they have. The floor is binding for projects that depend on admob-cmp-core directly without Compose, where the Kotlin version is not otherwise constrained.

PlatformSDKVersionHow it arrives
AndroidGoogle Mobile Ads Next-Gen1.3.0Transitive Maven dependency
AndroidUser Messaging Platform4.0.0Transitive, also pulled by GMA
iOSGoogleMobileAds13.7.0 headers; add the 13.x SPM packageYou add the Swift package
iOSGoogleUserMessagingPlatform3.1.0 headers; add the 3.x SPM packageYou add the Swift package

The rule that follows from bindings-only distribution: the SPM-resolved GMA major version must match the major these bindings were generated against. A package older than the bound headers fails to link on newly-added API symbols; the fix is to bump the SPM package. The iOS setup guide has the executable steps.

A note on “newer” SPM packages. A GMA SPM package newer than the bound headers is unsupported rather than supported, because the library has not validated the consumer’s app against the new symbols. In practice, the failure mode is a link-time undefined symbol for an Objective-C class the new package introduces, which is the same failure mode as a too-old package — the difference is the direction. The supported range is the bound major version and any patch within it.

The SDK is consumable from Kotlin Multiplatform and Gradle projects only — it compiles into the consumer’s umbrella framework. A pure-Swift iOS app cannot adopt it without a Kotlin Multiplatform shim. This is a deliberate consequence of the bindings-only distribution model: the iOS artifact has no Swift-callable surface, because cinterop generates a Kotlin-callable surface, not a Swift one.

A pure-Swift consumer would need a thin Kotlin module that exposes the relevant controllers as Swift-callable functions. The shape of that module is the consumer’s choice, but the absence of one is why a greenfield SwiftUI project cannot adopt admob-cmp directly. The roadmap discusses the long-term direction, which would make this kind of project viable.