demo.mp4
Experimental — APIs may change without notice. Relies on
react-native-workletsbundle mode, which is not enabled by default yet.
WebGPU-powered 3D model viewer for React Native. Load .glb (glTF Binary) models and display them in your app with real-time rendering on a dedicated background thread.
- WebGPU rendering via
react-native-wgpu - Off-thread rendering using
react-native-workletsbundle mode -- the GPU render loop runs on a separate JS runtime, keeping the main thread free - GLB model loading with built-in parser (positions, normals, texCoords, textures)
- Orbit camera with pan and pinch gestures (
react-native-gesture-handler) - Lighting presets (studio, outdoor, neutral) with configurable intensity
- Auto-rotation around any axis
npm install react-native-3dnpm install react-native-wgpu react-native-worklets react-native-gesture-handlerThis library relies on react-native-worklets Bundle Mode. You need to configure Metro and Babel in your app:
babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
['react-native-worklets/plugin', { bundleMode: true, strictGlobal: true }],
],
};metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { bundleModeMetroConfig } = require('react-native-worklets/bundleMode');
module.exports = mergeConfig(
getDefaultConfig(__dirname),
bundleModeMetroConfig
);package.json (add at root level)
{
"worklets": {
"staticFeatureFlags": {
"BUNDLE_MODE_ENABLED": true,
"FETCH_PREVIEW_ENABLED": true
}
}
}import { Preview3D } from 'react-native-3d';
export default function ModelViewer() {
return (
<Preview3D
url="https://modelviewer.dev/shared-assets/models/Astronaut.glb"
style={{ width: '100%', height: 300 }}
lighting={{ preset: 'studio' }}
autoRotate={{ axis: 'y', speed: 1 }}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
url |
string |
required | URL of the .glb model |
lighting |
{ preset?, intensity?, ambient? } |
{ preset: 'studio' } |
Lighting configuration |
gestures |
boolean |
true |
Enable pan/pinch camera gestures |
autoRotate |
{ axis?: 'x'|'y', speed?: number } |
- | Continuous rotation |
initialAngleX |
number |
0 |
Initial X rotation (radians) |
initialAngleY |
number |
0 |
Initial Y rotation (radians) |
initialZoom |
number |
1 |
Initial zoom level |
loading |
ReactNode |
<ActivityIndicator /> |
Custom loading indicator |
style |
ViewStyle |
- | Container style |
onLoad |
() => void |
- | Called when first frame renders |
onError |
(error: Error) => void |
- | Called on failure |
MIT