diff --git a/apps/example/app.json b/apps/example/app.json
index db73dc6d8..73135e124 100644
--- a/apps/example/app.json
+++ b/apps/example/app.json
@@ -27,7 +27,18 @@
]
},
"ios": {
- "metalAPIValidation": false
+ "metalAPIValidation": false,
+ "infoPlist": {
+ "NSCameraUsageDescription": "$(PRODUCT_NAME) needs access to your Camera.",
+ "NSMicrophoneUsageDescription": "$(PRODUCT_NAME) needs access to your Microphone."
+ }
+ },
+ "android": {
+ "permissions": [
+ { "android:name": "android.permission.INTERNET" },
+ { "android:name": "android.permission.CAMERA" },
+ { "android:name": "android.permission.RECORD_AUDIO" }
+ ]
},
"macos": {
"metalAPIValidation": false
diff --git a/apps/example/ios/Podfile.lock b/apps/example/ios/Podfile.lock
index 87a3ba3cc..e21cd966e 100644
--- a/apps/example/ios/Podfile.lock
+++ b/apps/example/ios/Podfile.lock
@@ -8,6 +8,65 @@ PODS:
- hermes-engine (0.81.4):
- hermes-engine/Pre-built (= 0.81.4)
- hermes-engine/Pre-built (0.81.4)
+ - NitroImage (0.14.0):
+ - boost
+ - DoubleConversion
+ - fast_float
+ - fmt
+ - glog
+ - hermes-engine
+ - NitroModules
+ - RCT-Folly
+ - RCT-Folly/Fabric
+ - RCTRequired
+ - RCTTypeSafety
+ - React-callinvoker
+ - React-Core
+ - React-debug
+ - React-Fabric
+ - React-featureflags
+ - React-graphics
+ - React-ImageManager
+ - React-jsi
+ - React-NativeModulesApple
+ - React-RCTFabric
+ - React-renderercss
+ - React-rendererdebug
+ - React-utils
+ - ReactCodegen
+ - ReactCommon/turbomodule/bridging
+ - ReactCommon/turbomodule/core
+ - SocketRocket
+ - Yoga
+ - NitroModules (0.35.7):
+ - boost
+ - DoubleConversion
+ - fast_float
+ - fmt
+ - glog
+ - hermes-engine
+ - RCT-Folly
+ - RCT-Folly/Fabric
+ - RCTRequired
+ - RCTTypeSafety
+ - React-callinvoker
+ - React-Core
+ - React-debug
+ - React-Fabric
+ - React-featureflags
+ - React-graphics
+ - React-ImageManager
+ - React-jsi
+ - React-NativeModulesApple
+ - React-RCTFabric
+ - React-renderercss
+ - React-rendererdebug
+ - React-utils
+ - ReactCodegen
+ - ReactCommon/turbomodule/bridging
+ - ReactCommon/turbomodule/core
+ - SocketRocket
+ - Yoga
- RCT-Folly (2024.11.18.00):
- boost
- DoubleConversion
@@ -2460,7 +2519,7 @@ PODS:
- ReactCommon/turbomodule/core
- SocketRocket
- Yoga
- - RNReanimated (4.3.1):
+ - RNReanimated (4.2.1):
- boost
- DoubleConversion
- fast_float
@@ -2487,12 +2546,11 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- - RNReanimated/apple (= 4.3.1)
- - RNReanimated/common (= 4.3.1)
+ - RNReanimated/reanimated (= 4.2.1)
- RNWorklets
- SocketRocket
- Yoga
- - RNReanimated/apple (4.3.1):
+ - RNReanimated/reanimated (4.2.1):
- boost
- DoubleConversion
- fast_float
@@ -2519,10 +2577,11 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
+ - RNReanimated/reanimated/apple (= 4.2.1)
- RNWorklets
- SocketRocket
- Yoga
- - RNReanimated/common (4.3.1):
+ - RNReanimated/reanimated/apple (4.2.1):
- boost
- DoubleConversion
- fast_float
@@ -2552,7 +2611,7 @@ PODS:
- RNWorklets
- SocketRocket
- Yoga
- - RNWorklets (0.8.3):
+ - RNWorklets (0.7.2):
- boost
- DoubleConversion
- fast_float
@@ -2579,11 +2638,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- - RNWorklets/apple (= 0.8.3)
- - RNWorklets/common (= 0.8.3)
+ - RNWorklets/worklets (= 0.7.2)
- SocketRocket
- Yoga
- - RNWorklets/apple (0.8.3):
+ - RNWorklets/worklets (0.7.2):
- boost
- DoubleConversion
- fast_float
@@ -2610,9 +2668,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
+ - RNWorklets/worklets/apple (= 0.7.2)
- SocketRocket
- Yoga
- - RNWorklets/common (0.8.3):
+ - RNWorklets/worklets/apple (0.7.2):
- boost
- DoubleConversion
- fast_float
@@ -2642,6 +2701,37 @@ PODS:
- SocketRocket
- Yoga
- SocketRocket (0.7.1)
+ - VisionCamera (5.0.10):
+ - boost
+ - DoubleConversion
+ - fast_float
+ - fmt
+ - glog
+ - hermes-engine
+ - NitroImage
+ - NitroModules
+ - RCT-Folly
+ - RCT-Folly/Fabric
+ - RCTRequired
+ - RCTTypeSafety
+ - React-callinvoker
+ - React-Core
+ - React-debug
+ - React-Fabric
+ - React-featureflags
+ - React-graphics
+ - React-ImageManager
+ - React-jsi
+ - React-NativeModulesApple
+ - React-RCTFabric
+ - React-renderercss
+ - React-rendererdebug
+ - React-utils
+ - ReactCodegen
+ - ReactCommon/turbomodule/bridging
+ - ReactCommon/turbomodule/core
+ - SocketRocket
+ - Yoga
- Yoga (0.0.0)
DEPENDENCIES:
@@ -2652,6 +2742,8 @@ DEPENDENCIES:
- fmt (from `../../../node_modules/react-native/third-party-podspecs/fmt.podspec`)
- glog (from `../../../node_modules/react-native/third-party-podspecs/glog.podspec`)
- hermes-engine (from `../../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
+ - NitroImage (from `../../../node_modules/react-native-nitro-image`)
+ - NitroModules (from `../../../node_modules/react-native-nitro-modules`)
- RCT-Folly (from `../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTDeprecation (from `../../../node_modules/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation`)
- RCTRequired (from `../../../node_modules/react-native/Libraries/Required`)
@@ -2726,6 +2818,7 @@ DEPENDENCIES:
- RNReanimated (from `../../../node_modules/react-native-reanimated`)
- RNWorklets (from `../../../node_modules/react-native-worklets`)
- SocketRocket (~> 0.7.1)
+ - VisionCamera (from `../../../node_modules/react-native-vision-camera`)
- Yoga (from `../../../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS:
@@ -2748,6 +2841,10 @@ EXTERNAL SOURCES:
hermes-engine:
:podspec: "../../../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
:tag: hermes-2025-07-07-RNv0.81.0-e0fc67142ec0763c6b6153ca2bf96df815539782
+ NitroImage:
+ :path: "../../../node_modules/react-native-nitro-image"
+ NitroModules:
+ :path: "../../../node_modules/react-native-nitro-modules"
RCT-Folly:
:podspec: "../../../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTDeprecation:
@@ -2892,6 +2989,8 @@ EXTERNAL SOURCES:
:path: "../../../node_modules/react-native-reanimated"
RNWorklets:
:path: "../../../node_modules/react-native-worklets"
+ VisionCamera:
+ :path: "../../../node_modules/react-native-vision-camera"
Yoga:
:path: "../../../node_modules/react-native/ReactCommon/yoga"
@@ -2903,6 +3002,8 @@ SPEC CHECKSUMS:
fmt: 530618a01105dae0fa3a2f27c81ae11fa8f67eac
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
hermes-engine: 35c763d57c9832d0eef764316ca1c4d043581394
+ NitroImage: 4ffcf183d975de179ae1662b7c3b4b3b37747c7e
+ NitroModules: 9ec4a2e0b9af22ba1f1f550e1dd9be94143afd18
RCT-Folly: b29feb752b08042c62badaef7d453f3bb5e6ae23
RCTDeprecation: c0ed3249a97243002615517dff789bf4666cf585
RCTRequired: 58719f5124f9267b5f9649c08bf23d9aea845b23
@@ -2973,9 +3074,10 @@ SPEC CHECKSUMS:
ReactTestApp-DevSupport: 9b7bbba5e8fed998e763809171d9906a1375f9d3
ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf
RNGestureHandler: e37bdb684df1ac17c7e1d8f71a3311b2793c186b
- RNReanimated: 9d012d4031abc9df896f8a82f9928eb2b9eae417
- RNWorklets: 0da2552f9ff5d17506918a692304110cfebb9f0a
+ RNReanimated: 464375ff2caa801358547c44eca894ff0bf68e74
+ RNWorklets: ee58e869ea579800ec5f2f1cb6ae195fd3537546
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
+ VisionCamera: 8c913d0cb2c868f779035fb69a1e0ab69e10f1c3
Yoga: a3ed390a19db0459bd6839823a6ac6d9c6db198d
PODFILE CHECKSUM: 22a8651333bf096f67ca333598bd33455d994c1f
diff --git a/apps/example/package.json b/apps/example/package.json
index bc1e36625..476341f0d 100644
--- a/apps/example/package.json
+++ b/apps/example/package.json
@@ -33,8 +33,11 @@
"react-native": "0.81.4",
"react-native-gesture-handler": "^2.28.0",
"react-native-macos": "^0.79.0",
+ "react-native-nitro-image": "0.14.0",
+ "react-native-nitro-modules": "0.35.7",
"react-native-reanimated": "4.2.1",
"react-native-safe-area-context": "^5.4.0",
+ "react-native-vision-camera": "5.0.10",
"react-native-web": "^0.21.2",
"react-native-wgpu": "*",
"react-native-worklets": "0.7.2",
diff --git a/apps/example/react-native.config.js b/apps/example/react-native.config.js
index 45416343e..75794451e 100644
--- a/apps/example/react-native.config.js
+++ b/apps/example/react-native.config.js
@@ -19,6 +19,27 @@ const project = (() => {
}
})();
+// Workaround: react-native-nitro-image's NitroImagePackage extends
+// BaseReactPackage, which @react-native-community/cli@13's autolinking regex
+// does not detect. Without this override, autolinking returns android: null
+// for nitro-image and vision-camera's gradle build fails with
+// "Project with path ':react-native-nitro-image' could not be found".
+const path = require("path");
+
module.exports = {
...(project ? { project } : undefined),
+ dependencies: {
+ "react-native-nitro-image": {
+ platforms: {
+ android: {
+ sourceDir: path.join(
+ __dirname,
+ "../../node_modules/react-native-nitro-image/android",
+ ),
+ packageImportPath: "import com.margelo.nitro.image.NitroImagePackage;",
+ packageInstance: "new NitroImagePackage()",
+ },
+ },
+ },
+ },
};
\ No newline at end of file
diff --git a/apps/example/src/App.tsx b/apps/example/src/App.tsx
index 0b26ab049..354a1c572 100644
--- a/apps/example/src/App.tsx
+++ b/apps/example/src/App.tsx
@@ -37,6 +37,7 @@ import { AsyncStarvation } from "./Diagnostics/AsyncStarvation";
import { DeviceLostHang } from "./Diagnostics/DeviceLostHang";
import { StorageBufferVertices } from "./StorageBufferVertices";
import { SharedTextureMemory } from "./SharedTextureMemory";
+import { Camera } from "./Camera";
// The two lines below are needed by three.js
import "fast-text-encoding";
@@ -102,6 +103,7 @@ function App() {
name="SharedTextureMemory"
component={SharedTextureMemory}
/>
+
diff --git a/apps/example/src/Camera/Camera.tsx b/apps/example/src/Camera/Camera.tsx
new file mode 100644
index 000000000..b0e9529a2
--- /dev/null
+++ b/apps/example/src/Camera/Camera.tsx
@@ -0,0 +1,60 @@
+import React, { useEffect } from "react";
+import { StyleSheet, Text, View } from "react-native";
+import {
+ Camera as VisionCamera,
+ useCameraDevice,
+ useCameraPermission,
+} from "react-native-vision-camera";
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: "black",
+ },
+ camera: {
+ flex: 1,
+ },
+ centered: {
+ flex: 1,
+ alignItems: "center",
+ justifyContent: "center",
+ padding: 24,
+ },
+ message: {
+ color: "white",
+ textAlign: "center",
+ },
+});
+
+export const Camera = () => {
+ const { hasPermission, requestPermission } = useCameraPermission();
+ const device = useCameraDevice("back");
+
+ useEffect(() => {
+ if (!hasPermission) {
+ requestPermission();
+ }
+ }, [hasPermission, requestPermission]);
+
+ if (!hasPermission) {
+ return (
+
+ Requesting camera permission...
+
+ );
+ }
+
+ if (device == null) {
+ return (
+
+ No camera device available.
+
+ );
+ }
+
+ return (
+
+
+
+ );
+};
diff --git a/apps/example/src/Camera/index.ts b/apps/example/src/Camera/index.ts
new file mode 100644
index 000000000..17290593b
--- /dev/null
+++ b/apps/example/src/Camera/index.ts
@@ -0,0 +1 @@
+export { Camera } from "./Camera";
diff --git a/apps/example/src/Home.tsx b/apps/example/src/Home.tsx
index 2db838041..74c153c0f 100644
--- a/apps/example/src/Home.tsx
+++ b/apps/example/src/Home.tsx
@@ -131,6 +131,10 @@ export const examples = [
screen: "SharedTextureMemory",
title: "🎞️ Shared Texture Memory",
},
+ {
+ screen: "Camera",
+ title: "📷 Camera",
+ },
];
const styles = StyleSheet.create({
diff --git a/apps/example/src/Route.ts b/apps/example/src/Route.ts
index 1f2dbf187..5c43b2a36 100644
--- a/apps/example/src/Route.ts
+++ b/apps/example/src/Route.ts
@@ -30,4 +30,5 @@ export type Routes = {
DeviceLostHang: undefined;
StorageBufferVertices: undefined;
SharedTextureMemory: undefined;
+ Camera: undefined;
};
diff --git a/yarn.lock b/yarn.lock
index f6a59461c..78e07a5b2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4965,9 +4965,12 @@ __metadata:
react-native: 0.81.4
react-native-gesture-handler: ^2.28.0
react-native-macos: ^0.79.0
+ react-native-nitro-image: 0.14.0
+ react-native-nitro-modules: 0.35.7
react-native-reanimated: 4.2.1
react-native-safe-area-context: ^5.4.0
react-native-test-app: 4.4.10
+ react-native-vision-camera: 5.0.10
react-native-web: ^0.21.2
react-native-wgpu: "*"
react-native-worklets: 0.7.2
@@ -12769,6 +12772,27 @@ __metadata:
languageName: node
linkType: hard
+"react-native-nitro-image@npm:0.14.0":
+ version: 0.14.0
+ resolution: "react-native-nitro-image@npm:0.14.0"
+ peerDependencies:
+ react: "*"
+ react-native: "*"
+ react-native-nitro-modules: "*"
+ checksum: ea5d19665bdffc8bb38fd5fef78a7d9c5f3f033cf0e0b6c224a39f718b863f3de74d776765eb7f5440743e985e2ea6c9ab210a1545947b0dcf02570408af5877
+ languageName: node
+ linkType: hard
+
+"react-native-nitro-modules@npm:0.35.7":
+ version: 0.35.7
+ resolution: "react-native-nitro-modules@npm:0.35.7"
+ peerDependencies:
+ react: "*"
+ react-native: "*"
+ checksum: 61f10d28b1e207361abef39b522259b1cee829ad4b0e44b07586119e3503e0aa460e2c7a514702a6cec7cc575db9614a5469d204865e23bb296c149dff0e8b95
+ languageName: node
+ linkType: hard
+
"react-native-reanimated@npm:4.2.1, react-native-reanimated@npm:^4.2.1":
version: 4.2.1
resolution: "react-native-reanimated@npm:4.2.1"
@@ -12858,6 +12882,18 @@ __metadata:
languageName: node
linkType: hard
+"react-native-vision-camera@npm:5.0.10":
+ version: 5.0.10
+ resolution: "react-native-vision-camera@npm:5.0.10"
+ peerDependencies:
+ react: "*"
+ react-native: "*"
+ react-native-nitro-image: "*"
+ react-native-nitro-modules: "*"
+ checksum: 52ffda9cbf8ec06e2156f86f48cabe5fd83e76d6fd6c939b85fe50814e26d8af1796ddb22ceb58fd21017c615f40e5e559a74034b8b5224a05b790650f8f4d95
+ languageName: node
+ linkType: hard
+
"react-native-web@npm:^0.21.2":
version: 0.21.2
resolution: "react-native-web@npm:0.21.2"