Skip to content

Waypoint

Product tours and feature showcases for Compose Multiplatform.

Kotlin Compose 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.

Artifacts

Artifact Description Platforms Version
waypoint-core State machine, overlay, tooltip positioning, target registration Android, iOS, Desktop, Web (JS, Wasm) Maven Central
waypoint-material3 Material3-styled tooltip with navigation buttons and progress Android, iOS, Desktop, Web (JS, Wasm) Maven Central

Pick waypoint-core alone for full control over the tooltip UI, or waypoint-material3 for a ready-made Material3 experience. waypoint-material3 depends on waypoint-core transitively.

Features

  • Highlight styles

    Spotlight, Pulse, Border, Ripple, None, or fully Custom, set per step or host-wide.

  • Spotlight effects

    Decorate the cutout with Glow, SoftEdge, or a custom draw lambda.

  • Step navigation

    next, previous, goTo, stop, pause, resume, fully programmatic.

  • Interactive tutorials

    Let the user type and tap inside the highlighted element while the rest of the screen is blocked.

  • Event-driven progression

    Advance steps when the user clicks a button, types in a field, or scrolls.

  • Intro and outro cards

    Steps without a target are shown as a centered card.

  • Async gates

    Hold a step until a suspend block finishes: wait for API responses, animations, or navigation.

  • Cross-hierarchy tours

    Targets inside Dialog, BottomSheet, and Popup via WaypointOverlayHost.

  • Tour sequences

    Chain multiple tours together with auto-advance and optional shared persistence.

  • Persistent hints

    Ambient beacons on UI elements, independent from tours, with dismiss-and-persist.

  • Persistence

    Remember which tours a user has completed across sessions.

  • Keyboard navigation

    Arrow keys and Escape on Desktop and Web, configurable per key.

  • Analytics

    Track tour started, completed, cancelled, and per-step events.

  • Theming

    Customize colors, typography, dimensions via WaypointMaterial3Theme.

Quick example

enum class OnboardingTarget { SearchBar, AddButton, Profile }

@Composable
fun HomeScreen() {
    val tourState = rememberWaypointState {
        step(OnboardingTarget.SearchBar) {
            title = "Search"
            description = "Find anything in your workspace."
        }
        step(OnboardingTarget.AddButton) {
            title = "Create"
            description = "Add a new item with one tap."
        }
        step(OnboardingTarget.Profile) {
            title = "Your profile"
            description = "View and edit your account."
        }
    }

    WaypointMaterial3Host(state = tourState) {
        Column {
            SearchBar(Modifier.waypointTarget(tourState, OnboardingTarget.SearchBar))
            FloatingActionButton(
                onClick = {},
                modifier = Modifier.waypointTarget(tourState, OnboardingTarget.AddButton),
            ) { Icon(Icons.Default.Add, "Add") }
            IconButton(
                onClick = {},
                modifier = Modifier.waypointTarget(tourState, OnboardingTarget.Profile),
            ) { Icon(Icons.Default.Person, "Profile") }
        }
    }

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

Four entry points

Most apps only ever touch these:

API Purpose
rememberWaypointState { step(key) { ... } } DSL builder that creates a WaypointState with typed step definitions
Modifier.waypointTarget(state, key) Marks a composable as a tour target and registers its bounds
WaypointHost(state) { content } Host composable that renders the highlight + tooltip (docs)
WaypointMaterial3Host(state) { content } Same, with Material3-styled tooltip (docs)

Next steps

Contribution

Found a bug or want a new feature? Open an issue. Pull requests welcome. ❤

Find this library useful? ❤

Support it by joining stargazers. ⭐ 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