ViroReact 2.53.0 – ReactVision Cloud & ViroARPlaneSelector Rewrite
We're excited to announce ViroReact v2.53.0 — a major release that introduces ReactVisionClient as the default cloud provider, a complete rewrite of ViroARPlaneSelector, new Depth API support, and much more.
Breaking Changes
ViroARPlaneSelector Rewrite
ViroARPlaneSelector has been completely rewritten with a new scene-event-driven architecture. It no longer self-manages plane detection internally. Instead, you must forward anchor events from ViroARScene via refs:
const selectorRef = useRef<ViroARPlaneSelector>(null);
<ViroARScene
anchorDetectionTypes={["PlanesHorizontal", "PlanesVertical"]}
onAnchorFound={(a) => selectorRef.current?.handleAnchorFound(a)}
onAnchorUpdated={(a) => selectorRef.current?.handleAnchorUpdated(a)}
onAnchorRemoved={(a) => a && selectorRef.current?.handleAnchorRemoved(a)}
>
<ViroARPlaneSelector ref={selectorRef} alignment="Both" ... />
</ViroARScene>
Removed: maxPlanes prop has been removed.
Changed: onPlaneSelected now includes an optional tapPosition parameter.
ViroARSceneNavigator — provider replaces cloudAnchorProvider and geospatialAnchorProvider
provider replaces cloudAnchorProvider and geospatialAnchorProviderThe two separate props are merged into a single provider prop that controls both backends simultaneously. provider defaults to "reactvision" so the prop can be omitted entirely in most cases.
Before:
<ViroARSceneNavigator
cloudAnchorProvider="reactvision"
geospatialAnchorProvider="reactvision"
initialScene={{ scene: MyARScene }}
/>
After:
// defaults to "reactvision" — prop can be omitted
<ViroARSceneNavigator
initialScene={{ scene: MyARScene }}
/>
// Or to override:
<ViroARSceneNavigator
provider="arcore"
initialScene={{ scene: MyARScene }}
/>
ViroCloudAnchorProvider and ViroGeospatialAnchorProvider are now deprecated aliases for the new ViroProvider type. They still compile with a deprecation warning.
Expo plugin (withViro) — provider replaces cloudAnchorProvider and geospatialAnchorProvider
withViro) — provider replaces cloudAnchorProvider and geospatialAnchorProviderBefore:
["@reactvision/react-viro", {
"cloudAnchorProvider": "reactvision",
"geospatialAnchorProvider": "reactvision",
"rvApiKey": "...",
"rvProjectId": "..."
}]
After:
["@reactvision/react-viro", {
"provider": "reactvision",
"rvApiKey": "...",
"rvProjectId": "..."
}]
New Features
ReactVision Studio Platform - Default Anchor Provider
"reactvision" is now the default provider for both Cloud Anchors and Geospatial Anchors within ViroReact and will be the default provider on ViroARSceneNavigator. ReactVisionClient provides cross-platform cloud anchor and geospatial anchor support. To use the ReactVision provider, you need an rvApiKey and rvProjectId from ReactVision Studio — see the ReactVision Studio Setup guide. If you need Google's ARCore provider instead, set the provider to "arcore" explicitly.
New configuration keys for ReactVision credentials:
- Expo (
app.jsonplugin config):"rvApiKey"and"rvProjectId" - iOS (non-Expo):
RVApiKeyandRVProjectIdinInfo.plist - Android (non-Expo):
com.reactvision.RVApiKeyandcom.reactvision.RVProjectIdinAndroidManifest.xml
Depth API
New depth-related props on ViroARSceneNavigator:
depthEnabled— Enable depth sensing (default:false)depthDebugEnabled— Show depth debug visualizationpreferMonocularDepth— Prefer monocular depth on iOS
performARHitTest now returns a new "DepthPoint" result type when depth is enabled.
ViroARPlaneSelector New Props
hideOverlayOnSelection— Hide plane overlay after selectionmaterial— Custom material for plane visualizationonPlaneDetected/onPlaneRemoved— Callbacks for plane lifecycleuseActualShape— Use detected plane geometry (default:true)
ReactVision Cloud Anchors (RVCA)
Place persistent AR content that other users can find — no Google Cloud account required. RVCA is a proprietary closed-source SDK; its implementation is not part of the open-source ViroCore or react-viro distribution. The "reactvision" provider routes hostCloudAnchor / resolveCloudAnchor through the ReactVision platform. The existing hostCloudAnchor, resolveCloudAnchor, and onCloudAnchorStateChange API is unchanged regardless of provider.
Key features:
- Hosting: scan your environment briefly, then call
hostCloudAnchor. Returns an error immediately if the environment has not been sufficiently observed — no silent fallback. - Resolving: the SDK matches the live camera feed against stored anchor data and returns a pose once a confident localisation is established.
- Cross-platform: iOS host → Android resolve and vice versa is fully supported.
- TTL:
hostCloudAnchoraccepts attlDaysparameter (1–365) to control anchor expiry on the backend. - GPS tagging: set the device location before hosting to embed GPS coordinates as anchor metadata. Enables proximity search via
rvFindNearbyCloudAnchors.
8 new methods on arSceneNavigator for full CRUD and analytics on cloud anchors:
| Method | Description |
|---|---|
rvGetCloudAnchor(anchorId) | Fetch a single anchor record |
rvListCloudAnchors(limit, offset) | Paginated list of all project anchors |
rvUpdateCloudAnchor(id, name, desc, isPublic) | Rename / re-describe an anchor |
rvDeleteCloudAnchor(anchorId) | Permanently delete an anchor and its assets |
rvFindNearbyCloudAnchors(lat, lng, radius, limit) | GPS proximity search |
rvAttachAssetToCloudAnchor(id, url, size, name, type, userId) | Attach a hosted file |
rvRemoveAssetFromCloudAnchor(anchorId, assetId) | Remove an attached asset |
rvTrackCloudAnchorResolution(...) | Record resolve analytics manually |
See the updated Cloud Anchors documentation.
ReactVision Geospatial Anchor Management
7 new ReactVision-only methods for GPS-tagged anchors (backed by the proprietary RVCA SDK):
| Method | Description |
|---|---|
hostGeospatialAnchor(lat, lng, alt, altitudeMode) | Persist an anchor to the ReactVision backend so others can resolve it |
resolveGeospatialAnchor(platformUuid) | Fetch a hosted anchor from the backend and create a local AR anchor at its GPS position |
rvListGeospatialAnchors(limit, offset) | Paginated list |
rvGetGeospatialAnchor(anchorId) | Fetch a single geospatial anchor |
rvFindNearbyGeospatialAnchors(lat, lng, radius, limit) | GPS proximity search |
rvUpdateGeospatialAnchor(id, sceneAssetId, sceneId, name) | Update metadata |
rvDeleteGeospatialAnchor(anchorId) | Permanently delete |
createGeospatialAnchor, createTerrainAnchor, and createRooftopAnchor are now supported with provider="reactvision". Note that createGeospatialAnchor is local-only — it does not persist to any backend. Use hostGeospatialAnchor to persist an anchor so other users can resolve it, and resolveGeospatialAnchor to fetch and display anchors hosted by others. No VPS, no ARCore Geospatial API, and no ARCore pods are required.
See the updated Geospatial Anchors documentation.
Asset Upload API
rvUploadAsset(assetType, filename, data, appUserId) — uploads a file to ReactVision storage and returns a URL and asset ID. Supported assetType values: "3d-model", "image", "video", "audio". The returned asset ID can be linked to a geospatial anchor via rvUpdateGeospatialAnchor or to a cloud anchor via rvAttachAssetToCloudAnchor.
Requires the ReactVision provider to be configured in your project. See the Asset Uploads documentation.
New Geospatial Utilities
Two new helper functions exported from @reactvision/react-viro:
gpsToArWorld(devicePose, lat, lng, alt)— converts a GPS coordinate to an AR world-space[x, y, z]offset from the device's current geospatial pose.latLngToMercator(lat, lng)— converts a GPS coordinate to a metric 2D position. Building block forgpsToArWorldand custom geo math.
New ViroProvider Type
ViroProvider TypeCanonical union type "none" | "arcore" | "reactvision" exported from the package. Replaces the deprecated ViroCloudAnchorProvider and ViroGeospatialAnchorProvider types.
AR Plane Detection Improvements
- Plane detection now defaults to both horizontal and vertical — no need to set
anchorDetectionTypesexplicitly. - Objects placed via
ViroARPlaneSelectornow appear at the exact tap point, not the plane centre. onPlaneSelectedreceives the tap position as an additional argument:(plane, tapPosition?) => void.- New props:
onPlaneRemoved,hideOverlayOnSelection,material. useActualShapenow defaults totrue— polygon boundary used instead of bounding rect.- New public method
handleAnchorRemovedonViroARPlaneSelectorfor use in theonAnchorRemovedcallback.
Changes
- Geospatial page renamed to Geospatial Anchors to better reflect its scope
- Expo config plugin defaults updated —
cloudAnchorProviderandgeospatialAnchorProvidernow default to"reactvision"
Shader Modifier System — Major Expansion
Shader modifiers now support the full range of custom GPU effects:
- Custom textures — declare
uniform sampler2Din modifier code and pass textures viamaterialUniforms. Swap them at runtime withupdateShaderUniform. - Vertex → fragment data — use the new
varyingsfield to pass typed values from a Geometry modifier to a Surface or Fragment modifier (e.g. displacement amount driving roughness). - Scene depth access — set
requiresSceneDepth: trueon a fragment modifier to receivescene_depth_textureautomatically. Enables soft particles, contact glow, and intersection effects. - Live camera feed on geometry — set
requiresCameraTexture: trueto sample the AR camera on any surface. Platform differences (samplerExternalOESvssampler2D) handled invisibly. Enables magnifying glass, portal, refraction, and warp effects. - Deterministic ordering — modifiers now have a
priorityfield so engine internals never override your effects regardless of attachment order.
Bug Fixes
- Models with washed-out / overexposed colours — GLB and other 3D assets appeared too bright due to an emissive colour value being incorrectly added to all materials. Fixed.
- iOS video recording silent failure —
startVideoRecording/stopVideoRecordingwere broken on iOS 17+ with the New Architecture. MultipleAVAssetWriterandAVAudioSessionissues fixed; recording now falls back to video-only if audio fails. - Android crash when closing a scene with physics — null pointer dereference on scene close for physics-enabled nodes. Fixed.
- Android New Architecture dev menu error — "You should not use ReactNativeHost directly" error on startup. Fixed.
- Ghost planes in ViroARPlaneSelector — pre-allocated slot index mapping was non-deterministic causing planes to appear in wrong positions or persist after removal. Fully rewritten.
- Selected plane disappeared immediately on tap — opacity logic inversion fixed.
- Children rendered on every plane slot — children now rendered once, only on the selected plane.
onPlaneDetectedreturn value ignored — returningfalsefromonPlaneDetectedpreviously had no effect. Now correctly prevents the plane from being added to the visible set.- Removed planes not cleaned up — disappeared planes were never removed from internal state, accumulating over time.
handleAnchorRemovednow deletes the entry and resets selection if needed. - Plane updates silently dropped for large surfaces — ARKit update threshold logic was AND instead of OR; large planes (floors, walls) rarely updated. Fixed.
- Rapid plane updates dropped on initial detection — fixed 100 ms throttle replaced with adaptive rate (33 ms for first 20 updates, 66 ms thereafter).
Need Help?
If you're looking for support getting started or want an expert to help you build a comprehensive AR/VR application, look no further than our community Discord and our trusted experts.