react-native-3d
v0.1.0
Published
Experimental 3D rendering utilities for React Native apps.
Maintainers
Readme
react-native-3d
https://github.com/user-attachments/assets/324e4627-839b-4e27-b4e4-fc18ae2d65e1
Experimental -- APIs may change without notice. Relies on react-native-worklets bundle mode, which is not yet stable. Use with caution.
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.
Features
- 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
Installation
npm install react-native-3dPeer dependencies
npm install react-native-wgpu react-native-worklets react-native-gesture-handlerBundle mode setup
This 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
}
}
}Usage
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 }}
/>
);
}Props
| 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 |
Contributing
License
MIT
