Beautiful onboarding flows for React Native apps. Display onboarding exactly as designed in the Sequence editor with pixel-perfect rendering.
npm install sequence-react-native react-native-safe-area-context @react-native-async-storage/async-storageFor Expo:
npx expo install sequence-react-native react-native-safe-area-context @react-native-async-storage/async-storageThese are only needed if your flows use specific features:
@react-native-community/slider- For slider input components (uses built-in fallback if not installed)react-native-svg- For ring-style progress indicators (falls back to bar style)react-native-linear-gradient/expo-linear-gradient- For gradient backgroundsexpo-haptics- For haptic feedback on checklist selections
import { SequenceProvider } from 'sequence-react-native';
export default function App() {
return (
<SequenceProvider
config={{
appId: 'your-app-id',
apiKey: 'your-api-key',
}}
>
<YourApp />
</SequenceProvider>
);
}import { useState } from 'react';
import { OnboardingModal, useShouldShowOnboarding } from 'sequence-react-native';
function YourApp() {
const shouldShowOnboarding = useShouldShowOnboarding();
const [showOnboarding, setShowOnboarding] = useState(shouldShowOnboarding);
return (
<>
<YourMainContent />
<OnboardingModal
visible={showOnboarding}
onClose={() => setShowOnboarding(false)}
onComplete={(collectedData) => {
console.log('Onboarding completed!', collectedData);
setShowOnboarding(false);
}}
/>
</>
);
}For more control, use the FlowRenderer component directly:
import { FlowRenderer, useSequence } from 'sequence-react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
function OnboardingScreen() {
const { config } = useSequence();
if (!config) {
return <LoadingSpinner />;
}
return (
<SafeAreaProvider>
<FlowRenderer
screens={config.screens}
progressIndicator={config.progressIndicator}
transitions={config.transitions}
onComplete={(data) => {
console.log('Completed with data:', data);
}}
onCustomAction={(identifier) => {
if (identifier === 'signInWithApple') {
// Handle Apple Sign In
}
}}
/>
</SafeAreaProvider>
);
}Handle native screen types for platform-specific implementations:
<OnboardingModal
visible={visible}
onClose={handleClose}
onNativeScreen={(screen) => {
// Return a React Native component for native screens
if (screen.content.identifier === 'permissions') {
return <PermissionsScreen />;
}
return null;
}}
/>Register custom block types to extend the SDK:
<OnboardingModal
visible={visible}
onClose={handleClose}
renderCustomBlock={(identifier, props) => {
if (identifier === 'my-custom-widget') {
return <MyCustomWidget {...props} />;
}
return null;
}}
/>Configure the SDK manually for more control:
import { Sequence, SequenceProvider } from 'sequence-react-native';
// Configure manually (useful for dynamic configuration)
await Sequence.configure({
appId: 'your-app-id',
apiKey: 'your-api-key',
baseURL: 'https://custom-api.example.com', // Optional custom API URL
});
// Identify a user
await Sequence.identify('user-123');
// Fetch config manually
const config = await Sequence.fetchConfig();
// Track custom events
await Sequence.track('custom_event', 'screen-id', { custom: 'data' });Access the full Sequence context:
const {
isConfigured, // SDK is configured
isLoading, // Currently loading config
error, // Any error that occurred
config, // The onboarding configuration
screens, // Shortcut to config.screens
isOnboardingCompleted, // User has completed onboarding
experimentInfo, // A/B test experiment info
// Actions
configure, // Configure the SDK
fetchConfig, // Fetch onboarding config
identify, // Identify a user
reset, // Reset SDK state
markOnboardingCompleted, // Mark onboarding complete
} = useSequence();Simple hook to check if onboarding should be displayed:
const shouldShow = useShouldShowOnboarding();
// Returns true if not completed AND screens are availableGet just the screens array:
const screens = useOnboardingScreens();Full-screen modal for displaying onboarding:
| Prop | Type | Description |
|---|---|---|
visible |
boolean |
Control modal visibility |
onClose |
() => void |
Called when modal should close |
onComplete |
(data: CollectedData) => void |
Called when onboarding completes |
onNativeScreen |
(screen: Screen) => ReactNode |
Render native screens |
onCustomAction |
(identifier: string) => void |
Handle custom button actions |
renderCustomBlock |
(id: string, props?) => ReactNode |
Render custom block types |
renderLoading |
() => ReactNode |
Custom loading UI |
renderError |
(error, retry) => ReactNode |
Custom error UI |
config |
OnboardingConfig |
Use external config instead of fetching |
Core renderer component:
| Prop | Type | Description |
|---|---|---|
screens |
Screen[] |
Array of screens to render |
progressIndicator |
FlowProgressIndicator |
Progress bar configuration |
transitions |
ScreenTransitionConfig[] |
Screen transition settings |
initialScreenIndex |
number |
Starting screen index |
onComplete |
(data: CollectedData) => void |
Completion callback |
onNativeScreen |
(screen: Screen) => ReactNode |
Native screen renderer |
onCustomAction |
(identifier: string) => void |
Custom action handler |
renderCustomBlock |
(id: string, props?) => ReactNode |
Custom block renderer |
Data collected from user inputs during onboarding is passed to the onComplete callback:
onComplete={(collectedData) => {
// collectedData is a Record<string, string | string[] | number>
// Keys are the fieldName values from input/checklist/slider blocks
console.log(collectedData.user_name); // Input field
console.log(collectedData.interests); // Checklist (array)
console.log(collectedData.daily_budget); // Slider value
}}The SDK automatically tracks these events:
onboarding_started- When onboarding beginsscreen_viewed- Each time a screen is displayedscreen_completed- When user advances from a screenonboarding_completed- When user finishes the flow
For custom tracking:
import { Sequence } from 'sequence-react-native';
Sequence.track('custom_event', 'screen-id', {
custom_property: 'value',
});The SDK automatically handles A/B test experiments:
const { experimentInfo } = useSequence();
if (experimentInfo) {
console.log('Experiment:', experimentInfo.id);
console.log('Variant:', experimentInfo.variantName);
}The SDK scales content to match the design canvas (iPhone 15 Pro dimensions: 393×852 points). Content automatically scales to fit any device while maintaining aspect ratio.
For custom styling utilities:
import { scale, getStylingStyles, getScaleFactor } from 'sequence-react-native';
// Scale a pixel value
const scaledPadding = scale(24); // Scales 24px to device
// Get current scale factor
const factor = getScaleFactor(); // e.g., 1.0 on iPhone 15 Pro
// Convert BlockStyling to React Native styles
const styles = getStylingStyles(block.styling);The SDK is fully typed. Import types as needed:
import type {
Screen,
ContentBlock,
OnboardingConfig,
CollectedData,
ButtonAction,
} from 'sequence-react-native';- React Native 0.72+
- React 18+
- iOS 13+ / Android API 21+
MIT