react-native-nucleus
v0.3.3
Published
Core infrastructure for React Native applications, providing the basics to avoid repeating yourself when bootstrapping a new app.
Readme
React Native Nucleus
Core infrastructure for React Native applications, providing a robust foundation for subscription management and state persistence.
Features
- RevenueCat Integration: Seamless wrapper around
react-native-purchases. - Subscription Store: Powered by Zustand and MMKV for high-performance persistence.
- Type Safety: Built with strict TypeScript rules.
Installation
npm install react-native-nucleus react-native-purchases zustand react-native-mmkv @react-native-community/netinfo
# or
yarn add react-native-nucleus react-native-purchases zustand react-native-mmkv @react-native-community/netinfoSetup
Wrap your application with AppCoreProvider.
import { AppCoreProvider, NucleusConfig } from 'react-native-nucleus';
import * as appTranslations from './locales/translations';
// Best practice: Derive supported languages from your translations object
const supportedLanguages = Object.keys(appTranslations) as (keyof typeof appTranslations)[];
const config: NucleusConfig = {
revenueCat: {
iosApiKey: 'your_ios_key',
androidApiKey: 'your_android_key',
// Required: Triggered when the paywall flow is finished (success, error, or cancel)
onPaywallFlowEnd: () => {
// e.g., router.push('/home') or closing a modal
console.log('Paywall flow finished');
},
},
};
export default function App() {
return (
<AppCoreProvider config={config}>
<YourAppContent />
</AppCoreProvider>
);
}Usage
State Management (Zustand)
Nucleus provides two hooks to access the same global store, allowing for better semantic clarity in your components:
useAppCoreStore: General access to the entire state (isPro,language, etc).
Important: Always use specific selectors to avoid unnecessary re-renders.
Accessing Subscription State
import { useAppCoreStore } from 'react-native-nucleus';
const MyComponent = () => {
// Use a selector to only subscribe to isPro changes
const isPro = useAppCoreStore((state) => state.isPro);
if (isPro) {
return <PremiumContent />;
}
return <LockedContent />;
};Managing Language
import { useAppCoreStore } from 'react-native-nucleus';
const LanguageSwitcher = () => {
const language = useAppCoreStore((state) => state.language);
const { setLanguage } = useAppCoreStore.getState();
return (
<Button
title={`Current: ${language}. Change to PT`}
onPress={() => setLanguage('pt')}
/>
);
};Managing Purchases
Use the purchaseService to handle purchases and restorations imperatively.
import { purchaseService } from 'react-native-nucleus';
const restore = async () => {
try {
// Automatically updates the store state on success
await purchaseService.restorePurchases();
} catch (error) {
console.error(error);
}
};Paywalls & Customer Center
To use RevenueCat's Paywalls and Customer Center, you need to install react-native-purchases-ui.
npm install react-native-purchases-uiThen you can use the built-in methods in purchaseService:
import { purchaseService } from 'react-native-nucleus';
// Present Paywall (returns true if purchased/restored)
// Note: This also triggers the global `onPaywallFlowEnd` callback if configured
const showPaywall = async () => {
const purchased = await purchaseService.presentPaywall();
if (purchased) {
console.log('User is now Pro!');
}
};
// Present Customer Center
const showCustomerCenter = async () => {
await purchaseService.presentCustomerCenter();
};Configuration
| Property | Type | Description |
| :--- | :--- | :--- |
| revenueCat.iosApiKey | string | RevenueCat API Key for iOS |
| revenueCat.androidApiKey | string | RevenueCat API Key for Android |
| revenueCat.onPaywallFlowEnd | () => void | Callback triggered when paywall flow finishes (success, error, or cancel) |
## Testing
When testing components that use `react-native-nucleus`, you should mock the store and services.
### Jest Mock Example
```javascript
jest.mock('react-native-nucleus', () => ({
useAppCoreStore: (selector) =>
selector({
isPro: true,
language: 'en',
setIsPro: jest.fn(),
setLanguage: jest.fn(),
resetSubscription: jest.fn(),
}),
purchaseService: {
restorePurchases: jest.fn(),
purchasePackage: jest.fn(),
},
}));Architecture
- Store: Zustand with MMKV persistence.
- Services: Singleton classes for external integrations.
