r3f-xr-widgets
v0.3.1
Published
Reusable XR/VR widgets and utilities for React Three Fiber - includes resizable windows, 360° video player, splash screens, and XR helper components
Maintainers
Readme
r3f-xr-widgets
A collection of components and utilities for building WebXR experiences with React Three Fiber. Includes resizable windows, splash screens, eye-level positioning, and more.
Features
- EquirectPlayer - 360°/180° video player with XR Layer rendering and UIKit controls
- HorizonWindow - Draggable, resizable 3D windows with audio feedback and haptic responses
- QuadVideoPlayer - 2d video player using XR Layer rendering
- SplashScreen - Beautiful XR session entry with VR/AR mode selection
- EyeLevelGroup - Automatic eye-level positioning for comfortable viewing
- Audio & Haptics - Built-in positional audio and controller haptic feedback
Live Demos
View Live Demos - Interactive examples of all components
Try the demos in your VR headset or browser to see the components in action!
Installation
npm install r3f-xr-widgets
# or
pnpm add r3f-xr-widgets
# or
yarn add r3f-xr-widgetsPeer Dependencies
npm install react react-dom three @react-three/fiber @react-three/drei @react-three/xr @react-three/handle @react-three/uikit @react-three/uikit-default @react-three/uikit-lucide @preact/signals-core @react-spring/threeQuick Start
import { Canvas } from '@react-three/fiber'
import { XR, createXRStore } from '@react-three/xr'
import { ResizableWindow, SplashScreen, AudioEffects } from 'r3f-xr-widgets'
const store = createXRStore()
function App() {
return (
<>
<SplashScreen store={store}>
<h1>My VR App</h1>
<p>Click Enter VR to begin</p>
</SplashScreen>
<Canvas>
<XR store={store}>
<AudioEffects />
<ResizableWindow position={[0, 1.5, -1]}>
<mesh>
<boxGeometry />
<meshStandardMaterial color="hotpink" />
</mesh>
</ResizableWindow>
</XR>
</Canvas>
</>
)
}API
For detailed documentation, props, and examples, see the Documentation.
Components — View all →
HorizonWindow,ResizableWindow- Draggable 3D windowsEquirectPlayer,QuadVideoPlayer- video playersSplashScreen,EnterXRButton,EyeLevelGroup- XR session utilitiesAudioEffects,Hover,GitHubBadge- UI helpers
Hooks — API Reference →
useXRButtons- XR controller button/thumbstick eventsuseVideoXRControls- Video playback with XR controlsuseXRSessionModeSupportedPolling- Check XR mode supportuseVideoMetadata- Video dimensions and metadata
Utilities
vibrateOnEvent- Trigger haptic feedbackDEFAULT_EYE_LEVEL- Standard eye level (1.5m)
Development
Prerequisites
- Node.js 18+
- pnpm (recommended) or npm
Setup
# Install dependencies
pnpm install
# Build the library
pnpm build
# Build in watch mode (for development)
pnpm dev
# Run type checking
pnpm typecheckTesting
This library uses Vitest with browser mode for automated XR testing.
# Run all tests
pnpm testKey Features:
- Test XR interactions without physical hardware
- Programmatically control virtual XR controllers
- Run tests in CI/CD pipelines
Running Demos
To run a demo, cd into its directory and run pnpm dev:
cd demos/video-player && pnpm devAvailable demos:
demos/resizable-window/- Draggable/resizable windowsdemos/horizon-window/- Horizon-style windowsdemos/video-player/- 360° video playerdemos/3d-video/- 3D video playback
Project Structure
r3f-xr-widgets/
├── src/ # Library source (components, hooks, utils, assets)
├── demos/ # Demo applications
├── docs/ # VitePress documentation
└── dist/ # Built library (generated)Debugging
This library uses the debug package for logging. Debug output is disabled by default and can be enabled as needed.
Browser (Demos)
Enable debug logging in your browser console:
localStorage.debug = 'r3f-xr-widgets:*'
// Then refresh the pageTo enable specific namespaces:
localStorage.debug = 'r3f-xr-widgets:hooks:*' // Only hooks
localStorage.debug = 'r3f-xr-widgets:components:*' // Only componentsTo disable:
localStorage.removeItem('debug')
// Then refresh the pageTests
Enable debug logging in vitest browser tests using the DEBUG_LOGGING environment variable:
DEBUG_LOGGING='r3f-xr-widgets:*' pnpm test
DEBUG_LOGGING='r3f-xr-widgets:hooks:*' pnpm testNote: Colors are disabled by default in tests for cleaner output. This is accomplished by overriding the debug package's useColors function in the test setup, since the browser implementation of debug does not natively support disabling colors via environment variables. To enable colors:
DEBUG_COLORS=1 DEBUG_LOGGING='r3f-xr-widgets:*' pnpm testAvailable Namespaces
r3f-xr-widgets:*- All library logsr3f-xr-widgets:hooks:*- All hooks (xr-buttons, xr-session)r3f-xr-widgets:components:*- All components (enter-xr, horizon-window, video-xr, etc.)r3f-xr-widgets:materials:*- Material shaders (edge-uv, arc)r3f-xr-widgets:test:*- Test utilities (controller, setup)r3f-xr-widgets:icons:*- Icon components
Note: In Chromium-based browsers (Chrome, Edge, Brave), you may need to set the console log level to "Verbose" to see debug output.
Browser Support
- Desktop: Chrome, Edge, Firefox with WebXR support
- VR Headsets: Meta Quest (native browser), PC VR headsets via browser
- Requirements: HTTPS for WebXR features (development servers included)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT © Myers Carpenter
Acknowledgments
Core Components Attribution:
- The
ResizableWindow,HandleWithAudio, andvibrateOnEventutilities were adapted from the @react-three/xr editor example.
Built with:
- React Three Fiber - React renderer for Three.js
- @react-three/xr - WebXR hooks and components
- @react-three/drei - Useful helpers for R3F
- @react-three/handle - Drag and resize interactions
