@take-out/native-hot-update
v0.0.51
Published
Minimal, headless React Native hot update library.
Readme
@take-out/native-hot-update
Minimal, headless React Native hot update library.
Features
- Simple instance-based API
- Pluggable storage (MMKV, AsyncStorage, custom)
- Timeout protection (5s + 20s hard limit)
- Pre-release testing workflow
- Works with Expo & React Native
- Zero UI - bring your own components
Installation
bun add @take-out/native-hot-update react-native-mmkvQuick Start
1. Create Hot Updater Instance
// src/hotUpdater.ts
import { MMKV } from 'react-native-mmkv'
import { createHotUpdater } from '@take-out/native-hot-update'
import { createMMKVStorage } from '@take-out/native-hot-update/mmkv'
import { HotUpdater } from '@hot-updater/react-native'
const mmkv = new MMKV({ id: 'hot-updater' })
const hotUpdaterInstance = createHotUpdater({
serverUrl: 'https://your-update-server.com',
storage: createMMKVStorage(mmkv),
updateStrategy: 'appVersion',
})
// Export the hook and resolver
export const useOtaUpdater = hotUpdaterInstance.useOtaUpdater
export const hotUpdaterResolver = hotUpdaterInstance.createResolver()
export const hotUpdater = hotUpdaterInstance2. Wrap Your App
// app/index.tsx or App.tsx
import { HotUpdater } from '@hot-updater/react-native'
import { hotUpdaterResolver } from './hotUpdater'
function App() {
// Your app component
return <YourApp />
}
// IMPORTANT: You must wrap your app with HotUpdater.wrap
export default HotUpdater.wrap({
resolver: hotUpdaterResolver,
updateMode: 'manual', // Use manual mode with custom hooks
})(App)3. Use in Your App
// app/_layout.tsx
import { useOtaUpdater } from './hotUpdater'
export default function RootLayout() {
const { userClearedForAccess, progress } = useOtaUpdater({
enabled: true,
onUpdateDownloaded: (info) => {
console.info('Update downloaded:', info.id)
},
onError: (error) => {
console.error('Update failed:', error)
},
})
if (!userClearedForAccess) {
return <SplashScreen progress={progress} />
}
return <YourApp />
}3. Display Version Info
import { hotUpdater } from './hotUpdater'
import * as Application from 'expo-application'
export function VersionDisplay() {
const otaId = hotUpdater.getShortOtaId()
const channel = hotUpdater.getChannel()
return (
<Text>
v{Application.nativeApplicationVersion}
{otaId && ` (${otaId})`} • {channel}
</Text>
)
}4. Dev Tools
import { hotUpdater } from './hotUpdater'
import { Button, View, Text, Alert } from 'react-native'
export function DevUpdateTools() {
const handleCheckUpdate = async () => {
const update = await hotUpdater.checkForUpdate()
if (update) {
Alert.alert('Update available', `ID: ${update.id}`, [
{ text: 'Later' },
{ text: 'Reload', onPress: () => hotUpdater.reload() },
])
} else {
Alert.alert('No update available')
}
}
const handleCheckPreRelease = async () => {
const update = await hotUpdater.checkForUpdate({
channel: 'production-pre',
isPreRelease: true,
})
if (update) {
Alert.alert('Pre-release available', `ID: ${update.id}`, [
{ text: 'Later' },
{ text: 'Reload', onPress: () => hotUpdater.reload() },
])
}
}
return (
<View>
<Text>Current: {hotUpdater.getAppliedOta() || 'Native build'}</Text>
<Text>Channel: {hotUpdater.getChannel()}</Text>
<Button title="Check for Update" onPress={handleCheckUpdate} />
<Button title="Check Pre-release" onPress={handleCheckPreRelease} />
<Button title="Reload App" onPress={() => hotUpdater.reload()} />
</View>
)
}API
createHotUpdater(config)
Creates a hot updater instance.
Config:
serverUrl(string): Your hot update server URLstorage(HotUpdateStorage): Storage adapter for persisting stateupdateStrategy('appVersion' | 'fingerprint'): Update strategy (default: 'appVersion')
Returns: HotUpdaterInstance
useOtaUpdater(options?)
React hook for automatic update checking.
Options:
enabled(boolean): Enable/disable update checking (default: true)onUpdateDownloaded(function): Callback when update is downloadedonError(function): Callback on error
Returns:
userClearedForAccess(boolean): Whether user can access appprogress(number): Download progress (0-100)isUpdatePending(boolean): Whether update will apply on restart
Instance Methods
checkForUpdate(options?)- Manually check for updatesgetAppliedOta()- Get current OTA bundle IDgetShortOtaId()- Get short OTA IDgetIsUpdatePending()- Check if update is pendingreload()- Reload appgetBundleId()- Get current bundle IDgetMinBundleId()- Get minimum bundle IDgetChannel()- Get current channel
