Skip to content

Repository files navigation

Waypoint

Product tours and feature showcases for Compose Multiplatform.

Kotlin Compose MohamedRejeb Apache-2.0 Maven Central

A spotlight tour moving between targets, then switching to dark theme A hands-on step where the user types inside the highlighted field A tour scrolling a list and following the user into a bottom sheet

Waypoint walks your users through your app: it dims the screen, cuts a hole around the thing you want them to look at, and puts a tooltip next to it. You describe the steps in a small DSL, tag your composables with a modifier, and the library handles positioning, animation, scrolling and input blocking.

It runs on Android, iOS, Desktop and Web (JS and Wasm) from the same code.

What it does

  • Tours: spotlight, pulse, border or ripple highlights, with a tooltip that flips and clamps to stay on screen.
  • Hands-on steps: let the user type or tap inside the highlighted element while the rest of the screen is blocked, and move on when they have done it (advanceOn).
  • Works where your UI is: targets in scrolling lists are scrolled into view, and a tour can follow the user into a dialog or bottom sheet.
  • Steps that wait: hold a step until data has loaded or a screen has opened (beforeShow), skip steps that do not apply (showIf).
  • Beyond tours: persistent hints and beacons for the "new feature" dot that stays until dismissed.
  • Your design or ours: a Material3 tooltip out of the box, or draw your own with waypoint-core, which has no design opinions.
  • The boring parts: keyboard navigation, screen reader announcements, RTL, show-once persistence, analytics hooks, and state that survives configuration changes.

Installation

kotlin {
    sourceSets {
        commonMain.dependencies {
            // Material3 tooltip, includes waypoint-core
            implementation("com.mohamedrejeb.waypoint:waypoint-material3:0.1.0")

            // or core only, if you draw your own tooltip
            implementation("com.mohamedrejeb.waypoint:waypoint-core:0.1.0")
        }
    }
}

Built with Kotlin 2.4.20 and Compose Multiplatform 1.12.1. See installation for requirements and snapshots.

Quick start

Three things: describe the steps, tag the targets, wrap the screen in a host.

enum class Onboarding { Search, Add, Profile }

@Composable
fun HomeScreen() {
    // 1. Describe the steps
    val tour = rememberWaypointState {
        step(Onboarding.Search) {
            title = "Search"
            description = "Find anything in your workspace."
        }
        step(Onboarding.Add) {
            title = "Create"
            description = "Add a new item with one tap."
        }
        step(Onboarding.Profile) {
            title = "Your profile"
            description = "View and edit your account."
        }
    }

    // 3. Wrap the screen in a host
    WaypointMaterial3Host(state = tour) {
        Column {
            // 2. Tag the targets
            SearchBar(Modifier.waypointTarget(tour, Onboarding.Search))
            AddButton(Modifier.waypointTarget(tour, Onboarding.Add))
            ProfileButton(Modifier.waypointTarget(tour, Onboarding.Profile))
        }
    }

    LaunchedEffect(Unit) { tour.start() }
}

To turn a step into something the user does instead of something they read:

step(Onboarding.Search) {
    title = "Try a search"
    description = "Type something to continue."
    interaction = TargetInteraction.PassThrough
    advanceOn { snapshotFlow { query }.first { it.isNotEmpty() } }
}

Make it yours

One tour restyled live: spotlight, glow, pulse, border and ripple

The highlight is set for the whole tour or per step:

WaypointMaterial3Host(
    state = tour,
    highlightStyle = HighlightStyle.Spotlight(
        shape = SpotlightShape.Circle,
        effect = SpotlightEffect.Glow(),
    ),
) { /* ... */ }

Colors, typography and dimensions of the Material3 tooltip come from WaypointMaterial3Theme. If that is not enough, pass your own composable as tooltipContent and draw whatever you like.


Documentation

The full docs are at mohamedrejeb.github.io/compose-waypoint. Good places to start:

Sample

The recordings above come from the :sample module, a small trip planner whose onboarding is three chained tours, plus a Lab screen for trying every highlight and tooltip option live. It runs on all targets:

# Desktop
./gradlew :sample:run

# Android
./gradlew :sample:assembleDebug

# Web (Wasm)
./gradlew :sample:wasmJsBrowserDevelopmentRun

# Web (JS)
./gradlew :sample:jsBrowserDevelopmentRun

For iOS, open iosApp/ in Xcode and run.

Contribution

If you've found a bug or want a new feature, please open an issue. Pull requests are welcome. ❤️

Find this library useful? ❤️

Support it by joining stargazers for this repository. ⭐ Also, follow me on GitHub for more libraries.

License

Copyright 2026 Mohamed Rejeb

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Releases

Packages

Contributors

Languages