Documentation
Everything you need to integrate Upflux into your React Native or Capacitor app.
Introduction
Upflux is an over-the-air (OTA) update solution for React Native and Capacitor apps. It allows you to push JavaScript and asset updates directly to your users without going through the app store review process.
🚀 Why Upflux?
- • Instant updates without app store approval
- • Automatic rollback on errors
- • Multi-deployment support (staging, production)
- • Built-in analytics and monitoring
- • Works with React Native and Capacitor
Quick Start
1. Install the SDK
npm install @upfluxhq/react-native2. Initialize Upflux
import { Upflux } from '@upfluxhq/react-native';
const upflux = new Upflux({
appId: 'your-app-id',
deployment: 'production',
clientKey: 'upx_cli_xxxxx',
serverUrl: 'https://api.upflux.io'
});
await upflux.init();3. Check for Updates
const updateInfo = await upflux.checkForUpdates();
if (updateInfo.updateAvailable) {
const result = await upflux.downloadUpdate(updateInfo);
if (result.success) {
await upflux.applyUpdate(result);
}
}Installation
Upflux requires React Native 0.60 or higher. Install the SDK using your preferred package manager:
npm install @upfluxhq/react-nativeyarn add @upfluxhq/react-nativepnpm add @upfluxhq/react-native⚠️ Native Module Setup (Required)
You must configure your app to load OTA bundles. The native module is autolinked, but you need to add bundle loading logic.
Android (MainApplication.kt)
import com.upflux.UpfluxModule
class MainApplication : Application(), ReactApplication {
override val reactHost: ReactHost by lazy {
val customBundlePath = UpfluxModule.getJSBundleFile(this)
getDefaultReactHost(
context = applicationContext,
packageList = PackageList(this).packages,
jsBundleFilePath = customBundlePath
)
}
}Android (MainApplication.java - for Java projects)
import com.upflux.UpfluxModule;
@Override
protected String getJSBundleFile() {
String customBundle = UpfluxModule.getJSBundleFile(this);
if (customBundle != null) return customBundle;
return super.getJSBundleFile();
}iOS (AppDelegate.m - Objective-C)
#import <upflux_react_native/UpfluxModule.h>
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
NSURL *customBundle = [UpfluxModule bundleURL];
if (customBundle) return customBundle;
return [self bundleURL];
}iOS (AppDelegate.swift - Swift projects)
// Add to Bridging-Header.h:
// #import <upflux_react_native/UpfluxModule.h>
override func sourceURL(for bridge: RCTBridge) -> URL? {
if let customBundle = UpfluxModule.bundleURL() {
return customBundle
}
return bundleURL()
}Install CocoaPods
cd ios && pod installApps & Deployments
Upflux organizes your updates around Apps and Deployments.
📱 Apps
An app represents your mobile application. Each app has a unique App ID that you use to configure the SDK.
🚀 Deployments
Deployments are environments within your app. Common deployments include:
- • Production - Your live app used by real users
- • Staging - For testing before production
🔑 API Keys
Upflux uses two types of API keys:
- •
upx_pub_*- Publish Keys for CLI (releasing updates) - •
upx_cli_*- Client Keys for SDKs (checking/downloading updates)
Releases
A release is a bundle of JavaScript code and assets that you push to your users.
Release Label
A unique identifier like v1.0.0 or v1.2.3-hotfix
Binary Version Range
Target specific app versions like 1.0.0 - 1.2.x
Rollout Percentage
Gradually roll out to 10%, 50%, or 100% of users
Mandatory Flag
Force users to update immediately if critical
Scheduled Release
Schedule releases for a specific date and time
Scheduled Releases
Schedule releases to go live at a specific date and time. Perfect for coordinating updates with marketing campaigns, feature launches, or maintenance windows.
📅 How Scheduled Releases Work
- Create a release with the
--scheduleflag - The release is uploaded as a Draft
- Set the scheduled time in the Upflux Dashboard
- The release automatically goes live at the scheduled time
Creating a Scheduled Release
# Create a draft release for scheduling
upflux release \
--label v2.0.0 \
--schedule
# Output:
# ✓ Release uploaded successfully!
# Status: DRAFT
# 📅 Set schedule time in dashboard✅ Use Cases
- • Feature launches at specific times
- • Coordinated global releases
- • Low-traffic maintenance windows
- • Marketing campaign coordination
💡 Tips
- • Test with staging first
- • Consider timezone differences
- • Combine with rollout percentages
- • Monitor after release goes live
Update Strategies
⚡ Immediate Updates
Download and apply updates as soon as they're available. Best for critical fixes.
const update = await upflux.checkForUpdates();
if (update.updateAvailable) {
const result = await upflux.downloadUpdate(update);
await upflux.applyUpdate(result); // Restarts immediately
}🕐 Deferred Updates
Download in the background and apply on next app restart.
const update = await upflux.checkForUpdates();
if (update.updateAvailable) {
await upflux.downloadUpdate(update);
// Update applies on next app launch
}Configuration
The SDK is configured by passing an UpfluxConfig object to the constructor:
interface UpfluxConfig {
appId: string; // Your Upflux app ID
deployment: string; // Target deployment (e.g., 'production')
clientKey: string; // Client API key (upx_cli_xxx)
serverUrl: string; // Server URL
}init()
Initializes the SDK and resolves which bundle to load. Call this early in your app startup.
const startup = await upflux.init();
// Returns StartupBundle:
// {
// bundlePath: string | null, // Path to active bundle
// isUpdate: boolean, // Whether running an update
// version: string | null // Current release version
// }checkForUpdates()
Checks the server for available updates matching the device and app configuration.
const updateInfo = await upflux.checkForUpdates();
// Returns UpdateInfo:
// {
// updateAvailable: boolean,
// releaseLabel: string,
// downloadUrl: string,
// mandatory: boolean,
// description: string
// }downloadUpdate()
Downloads the update bundle and assets to local storage.
const result = await upflux.downloadUpdate(updateInfo, {
onProgress: (progress) => {
console.log(`Downloaded: ${progress.percent}%`);
}
});
// Returns DownloadResult:
// {
// success: boolean,
// bundlePath: string,
// assetPaths: string[],
// error?: string
// }applyUpdate()
Applies the downloaded update and restarts/reloads the app.
const applyResult = await upflux.applyUpdate(downloadResult);
// Returns ApplyResult:
// {
// success: boolean,
// error?: string
// }
// Note: App will restart before this returns if successfulOther Methods
clearUpdate()
Clears the current update and reverts to the default bundle.
await upflux.clearUpdate();isInitialized()
Returns whether the SDK has been initialized.
const initialized = upflux.isInitialized(); // booleangetStartupBundle()
Returns startup bundle info from init().
const bundle = upflux.getStartupBundle();getConfig()
Returns the current SDK configuration.
const config = upflux.getConfig();destroy()
Destroys the SDK instance and cleans up resources.
upflux.destroy();upflux login
npm install -g @upfluxhq/cliAuthenticate with your publish key to enable releasing updates. Supports multiple credentials for different deployments.
# Non-interactive (recommended)
upflux login --key <publishKey>
# Example with multiple deployments
upflux login --key upx_pub_staging_xxxxx
upflux login --key upx_pub_production_xxxxx
# Credentials are stored locally in .upflux file⚠️ Never commit the .upflux file to version control. It contains your publish keys. Add it to your .gitignore.
upflux release
Create and publish a new release to your deployment.
React Native (Dual-Bundle - iOS & Android)
Creates separate bundles for iOS and Android automatically:
upflux release \
--label v1.0.0 \
--platform all \
--version-range ">=1.0.0" \
--rollout 100React Native (iOS Only)
Release only to iOS devices:
upflux release \
--label v1.0.1-ios-hotfix \
--platform ios \
--mandatoryReact Native (Android Only)
Release only to Android devices:
upflux release \
--label v1.0.1-android-hotfix \
--platform android \
--mandatoryCapacitor
Capacitor uses a single web bundle for all platforms:
# Build your web assets first
npm run build
# Release to Capacitor deployment
upflux release \
--label v1.0.0 \
--rollout 100Options
| Flag | Required | Description |
|---|---|---|
-l, --label | ✓ Required | Release label (e.g., v1.0.0) |
-p, --platform | Optional | Target platform: all, ios, or android (default: all for React Native) |
-v, --version-range | Recommended | Binary version range (e.g., >=1.0.0) |
-m, --mandatory | Optional | Force users to update immediately |
-r, --rollout | Optional | Rollout percentage (0-100, default: 100) |
-e, --entry-file | Optional | Entry file for bundler (default: index.js) |
-o, --output-dir | Optional | Output directory for bundle (default: ./dist) |
-b, --bundle | Optional | Skip bundling, use existing bundle file |
--skip-bundle | Optional | Skip bundling, use existing files in output dir |
--schedule | Optional | Create as draft, set schedule time in dashboard |
--capacitor | Optional | Force Capacitor mode (auto-detected if capacitor.config exists) |
--web-dir | Optional | Web directory for Capacitor (default: from config or www) |
upflux status
Check the status of your deployments and recent releases.
upflux status
# Shows:
# - Current deployment
# - Latest releases
# - Active devices count
# - Update success rateupflux logout
Remove stored credentials from the local machine.
# Interactive selection to remove one credential
upflux logout
# Remove all credentials at once
upflux logout --allupflux generate-manifest
Fetch and display the manifest for a specific release.
# Display manifest for a release
upflux generate-manifest --release-id <releaseId>
# Save manifest to a file
upflux generate-manifest --release-id <releaseId> --output manifest.json