Migration to v2
Voltra v2 introduces two major architectural changes:
- The old Voltra umbrella package is gone. Voltra now ships as separate iOS, Android, and server packages.
- The native layer moved from Expo Modules to Turbo Modules.
We made these changes to fix a few long-standing problems in the old package layout.
The old umbrella package made it too easy for React Native code to leak into server builds, especially when people only wanted server-side rendering or pre-rendering. It also forced many apps to pull in both platform surfaces even when they only shipped iOS or only shipped Android.
The Turbo Module migration also changes the native integration layer, so upgrading to v2 requires updating package installs, Expo plugin configuration, and some API usage.
This guide walks through the package, import, and configuration changes you need to make when upgrading to v2.
What changed
Package split
Old setups commonly used package paths like:
voltravoltra/clientvoltra/servervoltra/androidvoltra/android/clientvoltra/android/server
v2 uses scoped packages instead:
@use-voltra/ios@use-voltra/ios-client@use-voltra/ios-server@use-voltra/android@use-voltra/android-client@use-voltra/android-server@use-voltra/server
Platform-specific JSX namespaces
The old docs implied one shared component namespace. v2 documents the real platform split:
- iOS JSX primitives come from
@use-voltra/iosasVoltra - Android JSX primitives come from
@use-voltra/androidasVoltraAndroid - Android semantic color tokens also live in
@use-voltra/androidasAndroidDynamicColors - Android ongoing notification JSX lives in
@use-voltra/androidasAndroidOngoingNotification
Client APIs stay in *-client
Use @use-voltra/ios-client and @use-voltra/android-client for runtime APIs that run inside the React Native app, such as:
- starting or updating Live Activities
- updating widgets
- pinning Android widgets
- preview components such as
VoltraViewandVoltraWidgetPreview - event listeners and hooks
Server APIs are platform-specific
Use platform server packages for server-side rendering:
@use-voltra/ios-serverfor Live Activities and iOS widgets@use-voltra/android-serverfor Android widgets and ongoing notification payloads
Use @use-voltra/server only for cross-platform widget HTTP handlers.
Installation changes
Install the packages that match the layers you use.
iOS app code
Android app code
Optional server packages
Import mapping
iOS app code
iOS server code
Android widget code
Android server widget code
Expo plugin migration
The old docs used a single voltra plugin and nested per-platform config. v2 uses platform-specific plugins.
iOS
Android
API renames to watch for
- Android widget updates:
updateWidget(...)->updateAndroidWidget(...) - Android widget reloads:
reloadWidgets(...)for image-preloading remains, but widget refresh APIs usereloadAndroidWidgets(...) - Android widget server handlers:
createWidgetUpdateHandler(...)style examples should becomecreateAndroidWidgetUpdateHandler(...),createAndroidWidgetUpdateNodeHandler(...), orcreateAndroidWidgetUpdateExpressHandler(...) - iOS widget server handlers: use
createIOSWidgetUpdateHandler(...),createIOSWidgetUpdateNodeHandler(...), orcreateIOSWidgetUpdateExpressHandler(...)
Pre-render files
initialStatePath files run in Node during prebuild, not in the React Native runtime.
Use:
@use-voltra/iosfor iOS widget JSX and types@use-voltra/androidfor Android widget JSX and types
Do not import @use-voltra/ios-client or @use-voltra/android-client from pre-render files.
Recommended migration order
- Replace package installs.
- Swap the Expo plugin to the platform-specific package.
- Move JSX imports to
@use-voltra/iosor@use-voltra/android. - Move runtime APIs to the matching
*-clientpackage. - Move server rendering code to
@use-voltra/ios-serveror@use-voltra/android-server. - Rename Android widget APIs that became platform-specific.
- Verify
initialStatePathfiles only import from platform packages.
After migrating
Re-run prebuild for any platform whose plugin configuration changed:
