ViroReact 2.57.5: Eye-Gaze Input on Meta Quest Pro, Plus a Big Android AR Stability Pass

If you build AR on Android, this is the release to take.
ViroReact 2.57.5 is mostly a stability release. Four crash and freeze classes are gone, Android media capture finally behaves the way it should under scoped storage, and there is one new feature worth knowing about: eye-gaze input on Meta Quest Pro. No breaking changes, so this is a straight upgrade.
onGaze: eye-gaze hover arrives on Meta Quest Pro
Every Viro node now takes an optional onGaze event. It fires when the node is hovered by the user's eye-gaze ray, using XR_EXT_eye_gaze_interaction in the renderer.
The distinction from onHover matters. onHover fires for all input sources, controllers included. onGaze is eye-gaze only. Setting onGaze on its own is enough to enable hover on that node, so you do not need to wire up onHover alongside it.
On headsets without eye tracking (Quest 2, Quest 3, Quest 3S) it is a no-op, so you can ship the same scene everywhere and let the capable hardware light it up. That is the whole point of the ViroReact model: one codebase, and the renderer decides what each device can do.
Gaze is a natural fit for selection-heavy interfaces: menus, product configurators, training scenes where a user’s hands are already busy. It is worth prototyping now rather than waiting for gaze to become table stakes.
Four Android crashes and freezes, fixed
Scene-open freeze. Opening an AR scene with heavier content (3D models or video) could freeze the app for around 5 seconds on some devices, tripping an ANR. The cause was an interim camera-background workaround that replayed pause then resume on the UI thread, blocking the main thread in GLSurfaceView.onPause() while it waited on the GL thread. The renderer now handles camera-texture binding natively, so the workaround has been removed. The black-passthrough issue it originally guarded against stays fixed.
Animated glTF crash. Loading an animated model whose rig contained a zero-duration animation channel (a single keyframe, or all-zero times, both legal glTF) crashed with a native SIGSEGV. A divide-by-zero produced NaN keyframe times, which corrupted the sort in the renderer's skeletal-animation resampler. Guarded in the renderer. If you have been quietly re-exporting models to dodge this one, you can stop.
Anchor-retry crash. Leaving or switching an AR scene while a node’s anchor retry was still pending could crash in nativeCreateAnchoredNode. The retry now bails out when the parent scene is torn down, with a native null-ref guard behind it.
Async node methods no longer redbox or hang. getTransformAsync, getBoundingBoxAsync and getMorphTargets used to redbox or hang when called before the node was registered, a normal mount race that anyone using onProximity will have hit. They now reject cleanly with view_not_ready so you can retry or ignore quietly. Fixed on both iOS and Android.
Android media capture that actually writes files
Screenshots and video recordings on Android API 29+ were either silently failing (a raw write to public Pictures/ returning EACCES under scoped storage) or landing in app-private storage where the gallery could not see them.
Media now writes to app-specific storage, which always succeeds, and is published to the gallery through MediaStore when saveToCameraRoll is set. The permission gate has been corrected too: RECORD_AUDIO where it is needed, and WRITE_EXTERNAL_STORAGE only on API 28 and below.
If capture is part of your app’s share loop, and for most consumer AR it is, this is the fix that unblocks it.
Upgrading
No breaking changes. onGaze is purely additive and everything else is a bug or stability fix, so 2.57.5 is a drop-in upgrade from 2.57.x.
npm install @reactvision/react-viro@2.57.5ViroReact is open source and MIT licensed. If you hit something, raise it on GitHub. The Android reports in this release came straight from developers running real apps on real devices, and that is genuinely how these get found.