Guideway

Product tours, coachmarks, and onboarding for React Native - built for the New Architecture, where the old libraries broke.

MIT licensed  ·  verified on iOS & Android  ·  runs in Expo Go

Everything an onboarding flow needs.

And nothing that breaks on the New Architecture.

01

Animated spotlight

A Reanimated cutout glides between targets and reshapes - rectangle, rounded, circle, pill - entirely on the UI thread.

02

Tooltips that behave

Flip above or below, shift to stay on-screen, and clear the notch and home indicator. Safe-area aware, per-step placement.

03

Auto-scroll to anything

Off-screen targets scroll into view before they are highlighted - in a ScrollView, or a virtualized FlatList row via scrollToIndex.

04

Theming, free

Built-in light and dark, a colorScheme prop, tokens for color, radius, fonts, and labels - or replace the tooltip entirely.

05

Interactive spotlight

Let people tap through the hole to use the real element. Configurable scrim taps, and the keyboard dismisses on every step.

06

Show once, remember

showOnce tours fire on first launch and never nag again, through a pluggable storage adapter - AsyncStorage, MMKV, anything.

Why a new one

The established libraries were built for the old architecture and stopped working when Fabric became the default. Guideway started there.

CapabilityGuidewaycopilottourguidespotlight-tour
Works on the New Architecture (Fabric)Yes---
Animated, reshaping spotlightYes-YesYes
Auto-scroll to off-screen targetsYes---
FlatList / virtualized listsYes---
Light / dark theming built inYes---
Show-once persistenceYes---
Hook-first, no wrapper viewsYes--Yes

Shortened: react-native-copilot, rn-tourguide, react-native-spotlight-tour.

Up and running in a few lines

Mark a view with a ref, describe the tour as data, wrap the app. No HOCs, no wrapper views that shift your layout.

npx expo install guideway react-native-reanimated react-native-svg
Read the docs
import { TourProvider, useTour, useTourTarget } from 'guideway';

function Screen() {
  const search = useTourTarget('search');
  const { start } = useTour();
  return (
    <View>
      <TextInput ref={search} placeholder="Search" />
      <Button title="Show me around" onPress={() => start('main')} />
    </View>
  );
}

const tours = [{
  id: 'main',
  steps: [{ id: 'search', title: 'Find anything', body: 'Search here.' }],
}];

<TourProvider tours={tours}>
  <Screen />
</TourProvider>