OTA Compatibility
This page explains the rules for determining when OTA updates are safe and when a new store build is required.
The Core Rule
OTA updates can safely replace JavaScript code, but not native code.
If the native components of your app change, devices need a new binary from the app store.
What Can Be Updated via OTA
✅ JavaScript/TypeScript
All your app code:
// src/services/api.ts
export async function fetchData() {
// This can be updated via OTA
return await fetch('/api/data');
}✅ CSS/SCSS Styles
All styling:
/* app.css */
.button {
/* Can be updated via OTA */
background-color: blue;
}✅ Assets
Images, fonts, and other assets in your source:
src/
├── assets/
│ ├── images/
│ ├── fonts/
│ └── icons/✅ Non-Native npm Packages
Pure JavaScript packages:
{
"dependencies": {
"lodash": "4.17.21", // ✅ Safe to update
"axios": "1.4.0", // ✅ Safe to update
"date-fns": "2.30.0" // ✅ Safe to update
}
}✅ Node Modules (JavaScript Parts)
JavaScript code from any package, even native plugins:
node_modules/
└── nativescript-camera/
├── index.js // ✅ JS can update
└── platforms/
└── ios/ // ❌ Native cannotWhat Requires a Store Build
❌ NativeScript Platform Versions
{
"devDependencies": {
"@nativescript/ios": "8.6.0", // Change = store build
"@nativescript/android": "8.6.0" // Change = store build
}
}❌ Native Plugin Versions
Any plugin with native code:
{
"dependencies": {
"nativescript-camera": "4.5.0", // Change = store build
"@nativescript/imagepicker": "1.0.0", // Change = store build
"nativescript-geolocation": "8.0.0" // Change = store build
}
}❌ App_Resources Contents
App_Resources/
├── iOS/
│ ├── Info.plist // Change = store build
│ ├── Assets.xcassets/ // Change = store build
│ └── LaunchScreen.storyboard // Change = store build
└── Android/
├── AndroidManifest.xml // Change = store build
└── res/ // Change = store build❌ Custom Native Code
native-src/
├── ios/
│ └── MyBridge.swift // Change = store build
└── android/
└── MyBridge.java // Change = store buildCompatibility Checking Flow
1. Build Time
When you create a store build:
Project → Compute Fingerprint → Store with Build Record2. Update Time
When you publish an OTA update:
Project → Compute Fingerprint → Store with Update Record3. Check Time
When a device checks for updates:
Device Fingerprint ─┐
├─→ Compare ─┐
Update Fingerprint ─┘ │
▼
┌─────────────────────────────────┐
│ Match? │
│ │
│ Yes → Download OTA │
│ No → requiresStoreUpdate: true │
└─────────────────────────────────┘Client Behavior
Default Behavior
When requiresStoreUpdate is true:
- SDK receives the response
- Update is ignored
- App continues with current version
- Status:
UPDATE_IGNORED
Override Behavior
With allowStoreUpdateOverride: true:
initNorrix({
updateUrl: 'https://norrix.net',
allowStoreUpdateOverride: true, // ⚠️ Use with caution
});- SDK receives the response
- Update is downloaded despite incompatibility
- Update is applied
- Risk: App may crash if native code is missing
Warning: Only use this if you’re certain the native changes are backward-compatible.
Example Scenarios
Scenario 1: Bug Fix
Before: Version 1.0.0, Build 42
Change: Fix API endpoint in src/api.ts
After: Version 1.0.1, Build 43
→ ✅ OTA Compatible (JS only)Scenario 2: Plugin Update
Before: nativescript-camera@4.5.0
Change: npm update nativescript-camera@5.0.0
After: nativescript-camera@5.0.0
→ ❌ Store Build Required (native code changed)Scenario 3: New Icon
Before: AppIcon.png (original)
Change: Update App_Resources/iOS/Assets.xcassets
After: AppIcon.png (new design)
→ ❌ Store Build Required (App_Resources changed)Scenario 4: Mixed Changes
Changes:
- Fix bug in src/utils.ts ✅ JS
- Update @nativescript/core ❌ Native
→ ❌ Store Build Required (any native change triggers)Best Practices
Plan Updates Carefully
- Patch releases (1.0.1): Usually OTA-compatible
- Minor releases (1.1.0): Check for dependency changes
- Major releases (2.0.0): Often require store builds
Check Before Publishing
Always verify compatibility:
norrix fingerprint compare --from <last-build-id>Separate Concerns
- Keep native changes in dedicated releases
- Batch OTA-compatible changes together
- Communicate store updates to users
Version Strategy
1.0.0 (Store) → 1.0.1 (OTA) → 1.0.2 (OTA) → 1.1.0 (Store)