Overview
This guide will help you migrate from the legacy react-native-superwall SDK to the new expo-superwall SDK. The new SDK is built specifically for Expo and requires Expo SDK 53 or newer .
Expo SDK 53+ Required : This SDK only supports Expo SDK version 53 and newer. If you’re using an older Expo version, continue using the legacy React Native SDK .
Choose Your Migration Path
You have two options for migrating to expo-superwall:
Hooks-based SDK Recommended for most projects . Modern React hooks interface with better TypeScript support and developer experience.
Compat SDK Quick migration path . Drop-in replacement with minimal code changes. Uses the familiar class-based API.
If you’re starting a new project or want the best developer experience, choose the Hooks-based SDK . If you need to migrate quickly with minimal changes, use the Compat SDK .
Option 1: Hooks-based SDK
The hooks-based SDK provides a modern React interface with better state management and TypeScript support.
Step 1: Update Dependencies
First, uninstall the old package and install the new one:
npm uninstall react-native-superwall
npx expo install expo-superwall
Step 2: Replace Configuration
Old (react-native-superwall)
New (expo-superwall)
import Superwall from 'react-native-superwall' ;
// In your app initialization
await Superwall . configure ({
apiKey: 'your_api_key' ,
options: {
// options
},
});
Step 3: Migrate User Management
Old (react-native-superwall)
New (expo-superwall)
import Superwall from 'react-native-superwall' ;
// Identify user
await Superwall . shared . identify ({ userId: 'user_123' });
// Set user attributes
await Superwall . shared . setUserAttributes ({
name: 'John Doe' ,
email: '[email protected] ' ,
});
// Reset user
await Superwall . shared . reset ();
Step 4: Migrate Paywall Registration
Old (react-native-superwall)
New (expo-superwall)
import Superwall from 'react-native-superwall' ;
// Register placement
await Superwall . shared . register ({
placement: 'my_placement' ,
feature : () => {
// Feature logic
console . log ( 'Feature unlocked!' );
},
});
Step 5: Migrate Event Handling
Old (react-native-superwall)
New (expo-superwall)
import Superwall , { SuperwallDelegate } from 'react-native-superwall' ;
class MyDelegate extends SuperwallDelegate {
handleSuperwallEvent ( eventInfo ) {
console . log ( 'Event:' , eventInfo . event . type );
}
subscriptionStatusDidChange ( from , to ) {
console . log ( 'Subscription changed:' , from , to );
}
}
const delegate = new MyDelegate ();
await Superwall . shared . setDelegate ( delegate );
Step 6: Handle Loading States
The new SDK provides components to handle loading states:
import {
SuperwallProvider ,
SuperwallLoading ,
SuperwallLoaded ,
SuperwallError
} from 'expo-superwall' ;
export default function App () {
return (
< SuperwallProvider apiKeys = { { ios: API_KEY } } >
< SuperwallLoading >
< ActivityIndicator style = { { flex: 1 } } />
</ SuperwallLoading >
< SuperwallError >
{ ( error ) => (
< View style = { { flex: 1 , justifyContent: 'center' , alignItems: 'center' } } >
< Text > Failed to initialize: { error } </ Text >
</ View >
) }
</ SuperwallError >
< SuperwallLoaded >
< MainApp />
</ SuperwallLoaded >
</ SuperwallProvider >
);
}
Option 2: Compat SDK (Quick Migration)
For a faster migration path with minimal code changes, use the compat SDK. See the Compat SDK Guide for detailed instructions.
Breaking Changes
Version 1.0.0+
Removed : The collectAdServicesAttribution option has been removed. AdServices attribution is now collected automatically by the native iOS SDK.
Package Name
Old : react-native-superwall
New : expo-superwall
Minimum Requirements
Expo SDK : Version 53 or newer required
React Native : Version compatible with Expo SDK 53+
Configuration
SDK is now configured via <SuperwallProvider> component instead of imperative configure() call
API keys are now separated by platform (ios and android)
API Differences
Old API New Hooks API Notes Superwall.shared.identify()useUser().identify()Must be called inside a component Superwall.shared.setUserAttributes()useUser().update()Supports updater function Superwall.shared.reset()useUser().signOut()Renamed for clarity Superwall.shared.register()usePlacement().registerPlacement()Callbacks moved to hook options SuperwallDelegate classuseSuperwallEvents() hookEvent-based instead of class-based Superwall.shared.dismiss()useSuperwall().dismiss()Same functionality Superwall.shared.preloadAllPaywalls()useSuperwall().preloadAllPaywalls()Same functionality
New Configuration Options
Version 1.0.0 added several new configuration options:
< SuperwallProvider
apiKeys = { { ios: API_KEY } }
options = { {
// New iOS & Android option
shouldObservePurchases: true , // Observe purchases made outside Superwall
// New iOS-only options
shouldBypassAppTransactionCheck: false , // Disable app transaction check
maxConfigRetryCount: 6 , // Number of config fetch retries
// New Android-only option
useMockReviews: false , // Enable mock review functionality
} }
/>
Migration Checklist
Update dependencies
Uninstall react-native-superwall and install expo-superwall
Choose your approach
Decide between Hooks-based SDK (recommended) or Compat SDK (quick migration)
Update configuration
Replace Superwall.configure() with <SuperwallProvider> or Superwall.configure() in compat
Migrate user management
Update identify, setUserAttributes, and reset calls
Migrate paywall registration
Update placement registration calls
Migrate event handling
Replace SuperwallDelegate with event hooks or keep using compat delegate
Test thoroughly
Test all paywall flows, user identification, and event handling
Common Migration Issues
Issue: “Expo SDK version not supported”
Solution : Upgrade to Expo SDK 53 or newer, or continue using the legacy react-native-superwall package.
Solution : With the Hooks SDK, ensure your components are wrapped in <SuperwallProvider>. With the Compat SDK, call Superwall.configure() before accessing Superwall.shared.
Issue: “User attributes not updating”
// ❌ Wrong: Direct object
await update ({ name: 'John' });
// ✅ Correct: Use updater function to merge with existing attributes
await update (( oldAttributes ) => ({
... oldAttributes ,
name: 'John' ,
}));
Getting Help
If you encounter issues during migration:
Next Steps
Compat SDK Guide Learn about the quick migration path using the compatibility SDK
API Reference Explore the complete API documentation