Skip to content

Free vs Pro comparison paywall for Jetpack Compose

ComparisonPaywall is design 2 of M3 Expressive Paywall. Shows what the free tier includes and what Pro adds, as a table with a highlighted Pro column. Text values such as “50” vs “Unlimited” replace the icons where a limit is easier to read than a check mark.

Free vs Pro comparison paywall, light theme
Light
Free vs Pro comparison paywall, dark theme
Dark
implementation("com.github.sanikantv:m3-expressive-paywall:v1.0.0")
  • Your free tier is generous and users ask “what do I actually get?”
  • You want to show what is available without a subscription, which Google Play’s policy expects.
val rows = listOf(
ComparisonRow("Notes", free = true, freeText = "50", proText = "Unlimited"),
ComparisonRow("Basic themes", free = true),
ComparisonRow("Cloud sync", free = false),
ComparisonRow("Smart reminders", free = false),
ComparisonRow("Ad-free", free = false),
)
ComparisonPaywall(
plans = listOf(Sample.monthly, Sample.yearly),
rows = Sample.rows,
legal = Sample.legal,
onPurchase = buy,
onRestore = restore,
onClose = close,
freeLabel = "Basic",
proLabel = "Plus",
)
Parameter Type Default Description
plans List<PaywallPlan> required Plans shown as tiles side by side. Two or three fit best.
rows List<ComparisonRow> required Table rows. See ComparisonRow.
legal PaywallLegal required Terms and Privacy URLs for the footer links.
onPurchase (PaywallPlan) -> Unit required Called with the selected plan when the button is tapped. Start your billing flow here.
onRestore () -> Unit required Called from the Restore link.
onClose () -> Unit required Called from the close button.
modifier Modifier Modifier Applied to the paywall’s root.
title String “Free vs Pro” Headline.
subtitle String? “See exactly what you get when you upgrade.” Line under the headline.
freeLabel String “Free” Header of the free column.
proLabel String “Pro” Header of the highlighted column.
initialPlanId String? null Plan to preselect.

Full signature: ComparisonPaywall in the API reference.

Rename the columns with freeLabel and proLabel (“Basic” and “Plus” above). The Pro column uses primaryContainer, so it follows your theme.

  • Check and cross icons have content descriptions (“Included”, “Not included”), so the table reads correctly with TalkBack.
  • Plan tiles are radio options, like the plan cards in the other designs.
  • Too many rows. Six to eight rows keep the plans above the fold on most phones.
  • More than three plans: the tiles get narrow. Use the classic design for four or more.

Built by Sanikant. Set in Google Sans Flex (SIL Open Font License). Not affiliated with Google.