added

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

The 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

Before:

["@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.json plugin config): "rvApiKey" and "rvProjectId"
  • iOS (non-Expo): RVApiKey and RVProjectId in Info.plist
  • Android (non-Expo): com.reactvision.RVApiKey and com.reactvision.RVProjectId in AndroidManifest.xml

Depth API

New depth-related props on ViroARSceneNavigator:

  • depthEnabled — Enable depth sensing (default: false)
  • depthDebugEnabled — Show depth debug visualization
  • preferMonocularDepth — 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 selection
  • material — Custom material for plane visualization
  • onPlaneDetected / onPlaneRemoved — Callbacks for plane lifecycle
  • useActualShape — 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: hostCloudAnchor accepts a ttlDays parameter (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:

MethodDescription
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):

MethodDescription
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 for gpsToArWorld and custom geo math.

New ViroProvider Type

Canonical 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 anchorDetectionTypes explicitly.
  • Objects placed via ViroARPlaneSelector now appear at the exact tap point, not the plane centre.
  • onPlaneSelected receives the tap position as an additional argument: (plane, tapPosition?) => void.
  • New props: onPlaneRemoved, hideOverlayOnSelection, material.
  • useActualShape now defaults to true — polygon boundary used instead of bounding rect.
  • New public method handleAnchorRemoved on ViroARPlaneSelector for use in the onAnchorRemoved callback.

Changes

  • Geospatial page renamed to Geospatial Anchors to better reflect its scope
  • Expo config plugin defaults updated — cloudAnchorProvider and geospatialAnchorProvider now default to "reactvision"

Shader Modifier System — Major Expansion

Shader modifiers now support the full range of custom GPU effects:

  • Custom textures — declare uniform sampler2D in modifier code and pass textures via materialUniforms. Swap them at runtime with updateShaderUniform.
  • Vertex → fragment data — use the new varyings field 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: true on a fragment modifier to receive scene_depth_texture automatically. Enables soft particles, contact glow, and intersection effects.
  • Live camera feed on geometry — set requiresCameraTexture: true to sample the AR camera on any surface. Platform differences (samplerExternalOES vs sampler2D) handled invisibly. Enables magnifying glass, portal, refraction, and warp effects.
  • Deterministic ordering — modifiers now have a priority field 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 failurestartVideoRecording / stopVideoRecording were broken on iOS 17+ with the New Architecture. Multiple AVAssetWriter and AVAudioSession issues 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.
  • onPlaneDetected return value ignored — returning false from onPlaneDetected previously 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. handleAnchorRemoved now 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.

Join the ReactVision Discord →

Hire an Expert →