---
title: "Enhance in-app purchase experiences with slide to unlock in Jetpack Compose"
description: "In this article, you’ll explore the open-source slide-to-unlock library, built by RevenueCat, and learn how to integrate it with RevenueCat’s in-app purchases in Jetpack Compose "
language: "en"
publishedAt: "2025-09-24T08:13:37Z"
updatedAt: "2025-09-24T08:13:37Z"
authors:
  - name: "Jaewoong Eum"
    url: "https://www.revenuecat.com/blog/author/jaewoong-eum"
category: "Engineering"
categoryUrl: "https://www.revenuecat.com/blog/engineering"
readingTime: 4
canonical: "https://www.revenuecat.com/blog/engineering/compose-slide-to-unlock"
---

# Enhance in-app purchase experiences with slide to unlock in Jetpack Compose

In this article, you’ll explore the open-source slide-to-unlock library, built by RevenueCat, and learn how to integrate it with RevenueCat’s in-app purchases in Jetpack Compose 

## Table of contents

- [Slide to unlock in Jetpack Compose](#slide-to-unlock-in-jetpack-compose)
- [RevenueCat integration](#revenuecat-integration)
- [Building a custom paywalls with slide to unlock](#building-a-custom-paywalls-with-slide-to-unlock)
- [Wrapping Up](#wrapping-up)

When Apple first introduced the “Slide to Unlock” feature on the iPhone, it wasn’t just a quirky design, it was a deliberate interaction choice. Compared to a normal button, sliding offered a more engaging and meaningful way to unlock a device.

While newer devices have replaced “Slide to Unlock” with swipe gestures or biometric unlocking, the underlying principle remains the same: interaction should feel intentional, intuitive, and rewarding. Apple’s slider was one of the earliest examples of how even a simple UI decision can influence user engagement.

In this article, you’ll explore the open-source [slide-to-unlock library](https://github.com/revenueCat/slide-to-unlock/), built by RevenueCat, and learn how to integrate it with RevenueCat’s in-app purchases in Jetpack Compose through practical, real-world examples.

## Slide to unlock in Jetpack Compose

The slide-to-unlock library is designed for [Kotlin Multiplatform](https://kotlinlang.org/docs/multiplatform.html), so you can use it in both Android and KMP projects. To add slide-to-unlock to your project, include the following dependency in your Gradle file:

```kotlin
implementation("com.revenuecat.purchases:slide-to-unlock:1.0.2")
```

For Kotlin Multiplatform, add the dependency below to your module’s build.gradle.kts file:

```kotlin
sourceSets {
    val commonMain by getting {
        dependencies {
            implementation(libs.compose.slidetounlock)
        }
    }
}

```

The usage is pretty simple. You can just implement it by using the `SlideToUnlock` composable with creating a state at the call site like below:

```kotlin
var isSlided by remember { mutableStateOf(false) }

SlideToUnlock(
    isSlided = isSlided,
    modifier = Modifier.fillMaxWidth(),
    onSlideCompleted = { isSlided = true },
)
```

`SlideToUnlock` is highly customizable, you can adjust nearly every aspect of the slider, including [colors](https://github.com/revenueCat/slide-to-unlock/?tab=readme-ov-file#customizing-colors),[ thumb, hint text](https://github.com/revenueCat/slide-to-unlock/?tab=readme-ov-file#fully-customize-thumb-and-hint-composables), [gesture behavior](https://github.com/revenueCat/slide-to-unlock/?tab=readme-ov-file#customizing-the-gesture-behavior), and [tracking slide fractions](https://github.com/revenueCat/slide-to-unlock/?tab=readme-ov-file#tracking-slide-fraction-changes). You can also provide your own composables for the thumb and hint to achieve a fully tailored experience. For more details on customization, please refer to the [documentation](https://github.com/revenueCat/slide-to-unlock/).

## RevenueCat integration

This library supports RevenueCat integration, allowing you to easily implement features like *Slide to Purchase* or *Slide to Subscribe* by adding the dependency below:

```kotlin
implementation("com.revenuecat.purchases:slide-to-unlock-purchases:1.0.2")
```

You can now use the `SlideToPurchases` component, which triggers in-app purchases once the slide action is completed. Its usage is very similar to the `SlideToUnlock` composable, but it requires a few additional parameters needed to complete purchases through the RevenueCat SDK.

The library provides several overloaded `SlideToPurchases` composables to cover different purchase scenarios, such as product types, subscription upgrades, and promotional offers, while abstracting away the underlying purchase logic.The most common use case is simple: fetch your offerings from RevenueCat and pass the desired `Package` to the composable. The component takes care of everything else.

```kotlin
\/\/ inside your coroutine scope
val currentOffering = Purchases.sharedInstance.awaitOfferings().current
val monthlyPackage = currentOffering?.getPackage("monthly")

if (monthlyPackage != null) {
    var purchaseState by remember { mutableStateOf<PurchaseState?>(null) }

    SlideToPurchases(
        packageToPurchase = monthlyPackage,
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        onPurchaseStateChanged = { newPurchaseState ->
            purchaseState = newPurchaseState
            \/\/ Handle state changes, e.g., show a dialog on success\/error
        }
    )

    \/\/ Optionally display the state
    when (val state = purchaseState) {
        is PurchaseState.Loading -> { \/* Show a loading indicator *\/ }
        is PurchaseState.Success -> { \/* Navigate to a success screen *\/ }
        is PurchaseState.Error -> { \/* Show an error message *\/ }
        null -> { \/* Initial state *\/ }
    }
}
```

Similar to the `Purchases.sharedInstance.awaitPurchase()` function, you can perform in-app purchases using several options: `StoreProduct`, `Package`, `SubscriptionOption`, `PromotionalOffer`, and `WinBackOffer`. For more details, check out the[ overloads documentation](https://github.com/revenueCat/slide-to-unlock/?tab=readme-ov-file#overloads).

## Building a custom paywalls with slide to unlock

Now let’s take a look at how to build a custom paywall that includes *Slide to Unlock*. If you want to create your own custom paywalls, you can achieve it by using RevenueCat’s [Paywall Editor](https://www.revenuecat.com/docs/tools/paywalls/creating-paywalls#using-the-editor), which is based on a [server-driven UI](https://www.revenuecat.com/blog/engineering/server-driven-android/).

However, if you need a more personalized design, such as containing very customized UI components that aren’t supported by the Paywall Editor, you’ll need to create your own custom paywalls. In that case, you can manually fetch the current offerings and render the screens based on your requirements.

Currently, RevenueCat’s Paywall Editor doesn’t support Slide to Unlock officially, so in this article we’ll walk through a workaround for integrating it into your custom paywalls. First things first: open the RevenueCat Paywall Editor and create a new paywall without a footer, leaving enough space at the bottom like the image below:

![](https://cdn.sanity.io/images/c3qnx9b0/production/46d124fb1bdee532271bf40335d0c30f215ec0cf-1286x940.png)

Next, fetch the current offering as shown in the code below:

```kotlin
try {
  val offerings = Purchases.sharedInstance.awaitOfferings()
  offerings.current?.let { currentOffering ->
    \/\/ you have a current offering now here
  }
} catch (e: PurchasesException) {
  \/\/ fetching offering exception
}
```

Then, retrieve the available package information from the offering and position the `Paywall` composable component alongside `SlideToUnlock`, as demonstrated here:

```kotlin
 Box(
    modifier = Modifier
      .fillMaxSize()
      .background(Color.White),
  ) {
    Paywall(
      options = PaywallOptions.Builder(
        dismissRequest = { viewModel.navigateUp() },
      ).setOffering(offering).build(),
    )

    val availablePackage = offering?.availablePackages?.first()
    val activity = (LocalContext.current as? Activity)
    var isSlided by remember { mutableStateOf(false) }
    
    if (availablePackage != null && activity != null) {
      SlideToUnlock(
        modifier = Modifier
          .align(Alignment.BottomCenter)
          .fillMaxWidth()
          .padding(bottom = 60.dp, start = 20.dp, end = 20.dp),
        isSlided = isSlided,
        hintTexts = HintTexts.defaultHintTexts().copy(
          defaultText = stringResource(
            com.revenuecat.articles.paywall.compose.core.designsystem.R.string.slide_subscribe,
          ),
        ),
        onSlideCompleted = {
          isSlided = true
          viewModel.handleEvent(
            PaywallEvent.Purchases(
              activity = activity,
              availablePackage = availablePackage,
            ),
          )
        },
      )
    }
  }

```

That’s it! You’ll now see the result below, a seamless combination of the paywall you built in the Paywall Editor and the Slide to Unlock component.

![](https://cdn.sanity.io/images/c3qnx9b0/production/dd3b3bbe0eb7ba8362adb4fd5fa932a48d88c4c7-507x981.png)

You can check out the full source code on GitHub, an open source project [Cat Paywall Compose’s paywalls directory](https://github.com/RevenueCat/cat-paywall-compose/tree/main/feature/paywalls/src/main/kotlin/com/revenuecat/articles/paywall/paywalls).

## Wrapping Up

In this article, you’ve learned how to use the *[slide-to-unlock](https://github.com/revenueCat/slide-to-unlock/)*[ library](https://github.com/revenueCat/slide-to-unlock/) and integrate it into a custom paywall. While RevenueCat’s Paywall Editor offers a fast and convenient way to build paywalls, sometimes you’ll want to go further and experiment with more personalized or playful interactions.

There are many strategies to increase user engagement and improve subscription conversion rates, clear value communication, compelling design, optimized pricing, and interactive UI patterns all play a role. *Slide to Unlock* adds an extra layer of interactivity that feels intuitive, deliberate, and rewarding for users, helping to reduce friction and increase commitment to the purchase flow.

As you continue refining your paywalls, consider testing different designs, messaging, and engagement patterns to find what resonates best with your audience. Combined with [RevenueCat’s analytics](https://www.revenuecat.com/feature/charts/) and [A/B testing capabilities](https://www.revenuecat.com/feature/experiments/), approaches like *slide-to-unlock* can be great tools in building subscription experiences that are not only effective but also enjoyable.

---

## Related posts

- [Mark your models as stable with the Compose runtime annotation library](https://www.revenuecat.com/blog/engineering/compose-runtime-annotation)
- [remember vs rememberSaveable: deep dive into state management and recomposition in Jetpack Compose](https://www.revenuecat.com/blog/engineering/remember-vs-remembersaveable)
- [Server-driven UI SDK on Android: how RevenueCat enables remote paywalls without app updates](https://www.revenuecat.com/blog/engineering/server-driven-android)
