-
Notifications
You must be signed in to change notification settings - Fork 583
Description
Description
Description
When both @shopify/react-native-skia (v2.5.4) and react-native-wgpu (v0.5.9) are installed in the same project, the iOS build fails at the linker stage with 3 duplicate ObjC symbols (_OBJC_METACLASS_$_WebGPUView, _OBJC_CLASS_$_WebGPUView, WebGPUViewCls()). The project cannot be built at all.
This happens because both packages register a native component called WebGPUView through three independent mechanisms:
1. codegenConfig in package.json
Both packages declare WebGPUView in their codegenConfig.ios.componentProvider:
@shopify/react-native-skia/package.json:
"codegenConfig": {
"name": "rnskia",
"ios": {
"componentProvider": {
"SkiaPictureView": "SkiaPictureView",
"WebGPUView": "WebGPUView"
}
}
}react-native-wgpu/package.json:
"codegenConfig": {
"name": "RNWgpuViewSpec",
"ios": {
"componentProvider": {
"WebGPUView": "WebGPUView"
}
}
}The React Native codegen processes both during prebuild and generates duplicate native registrations.
2. JS codegen specs
Both packages have a WebGPUViewNativeComponent.js that calls codegenNativeComponent("WebGPUView"):
@shopify/react-native-skia/lib/module/specs/WebGPUViewNativeComponent.jsreact-native-wgpu/lib/module/WebGPUViewNativeComponent.js
3. Native ObjC files
Both packages ship their own WebGPUView.mm and WebGPUView.h, which are both compiled and linked into the final binary:
libreact-native-skia.acontainsWebGPUView.olibreact-native-wgpu.acontainsWebGPUView.o
Skia's podspec does not exclude these files in v2.5.4, causing the 3 duplicate linker symbols.
Use case
We use react-native-wgpu as a peer dependency of typegpu-confetti, which imports Canvas, useCanvasRef, and useDevice directly from react-native-wgpu. We can't remove it.
Workaround
We applied a patch-package patch to @shopify/react-native-skia that:
- Removes
WebGPUViewfromcodegenConfig.ios.componentProviderinpackage.json— stops the codegen from generating duplicate native registrations - Excludes
apple/WebGPUView.mmandapple/WebGPUView.hin the podspec — prevents duplicate native ObjC class compilation - Redirects the JS specs (
lib/module/specs/WebGPUViewNativeComponent.jsandlib/commonjs/...) to re-export fromreact-native-wgpuinstead of callingcodegenNativeComponentdirectly - Redirects the TS source spec (
src/specs/WebGPUViewNativeComponent.ts) similarly
After patching, a clean prebuild + native build resolves the crash.
Full patch file
diff --git a/node_modules/@shopify/react-native-skia/package.json b/node_modules/@shopify/react-native-skia/package.json
--- a/node_modules/@shopify/react-native-skia/package.json
+++ b/node_modules/@shopify/react-native-skia/package.json
@@ -147,8 +147,7 @@
},
"ios": {
"componentProvider": {
- "SkiaPictureView": "SkiaPictureView",
- "WebGPUView": "WebGPUView"
+ "SkiaPictureView": "SkiaPictureView"
}
}
},
diff --git a/node_modules/@shopify/react-native-skia/lib/module/specs/WebGPUViewNativeComponent.js b/node_modules/@shopify/react-native-skia/lib/module/specs/WebGPUViewNativeComponent.js
--- a/node_modules/@shopify/react-native-skia/lib/module/specs/WebGPUViewNativeComponent.js
+++ b/node_modules/@shopify/react-native-skia/lib/module/specs/WebGPUViewNativeComponent.js
@@ -1,4 +1,2 @@
-import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
-// eslint-disable-next-line import/no-default-export
-export default codegenNativeComponent("WebGPUView");
+// Re-export from react-native-wgpu to avoid duplicate registration
+export { default } from "react-native-wgpu/lib/module/WebGPUViewNativeComponent";
diff --git a/node_modules/@shopify/react-native-skia/lib/commonjs/specs/WebGPUViewNativeComponent.js b/node_modules/@shopify/react-native-skia/lib/commonjs/specs/WebGPUViewNativeComponent.js
--- a/node_modules/@shopify/react-native-skia/lib/commonjs/specs/WebGPUViewNativeComponent.js
+++ b/node_modules/@shopify/react-native-skia/lib/commonjs/specs/WebGPUViewNativeComponent.js
@@ -1,11 +1,8 @@
"use strict";
+// Re-export from react-native-wgpu to avoid duplicate registration
Object.defineProperty(exports, "__esModule", {
value: true
});
-exports.default = void 0;
-var _codegenNativeComponent = _interopRequireDefault(require("react-native/Libraries/Utilities/codegenNativeComponent"));
-function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
-// eslint-disable-next-line import/no-default-export
-var _default = exports.default = (0, _codegenNativeComponent.default)("WebGPUView");
+var _wgpu = require("react-native-wgpu/lib/commonjs/WebGPUViewNativeComponent");
+exports.default = _wgpu.default;
diff --git a/node_modules/@shopify/react-native-skia/src/specs/WebGPUViewNativeComponent.ts b/node_modules/@shopify/react-native-skia/src/specs/WebGPUViewNativeComponent.ts
--- a/node_modules/@shopify/react-native-skia/src/specs/WebGPUViewNativeComponent.ts
+++ b/node_modules/@shopify/react-native-skia/src/specs/WebGPUViewNativeComponent.ts
@@ -1,11 +1,2 @@
-import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
-import type { Int32 } from "react-native/Libraries/Types/CodegenTypes";
-import type { ViewProps } from "react-native";
-
-export interface NativeProps extends ViewProps {
- contextId: Int32;
- transparent: boolean;
-}
-
-// eslint-disable-next-line import/no-default-export
-export default codegenNativeComponent<NativeProps>("WebGPUView");
+// Re-export from react-native-wgpu to avoid duplicate registration
+export { default } from "react-native-wgpu/src/WebGPUViewNativeComponent";
diff --git a/node_modules/@shopify/react-native-skia/react-native-skia.podspec b/node_modules/@shopify/react-native-skia/react-native-skia.podspec
--- a/node_modules/@shopify/react-native-skia/react-native-skia.podspec
+++ b/node_modules/@shopify/react-native-skia/react-native-skia.podspec
@@ -97,7 +97,9 @@
'cpp/rnwgpu/**/*.{h,cpp}',
'cpp/jsi2/**/*.{h,cpp}'
]
- s.exclude_files = graphite_exclusions unless use_graphite
+ # Exclude WebGPUView — conflicts with react-native-wgpu which provides the canonical impl.
+ webgpu_view_exclusions = ['apple/WebGPUView.mm', 'apple/WebGPUView.h']
+ s.exclude_files = (use_graphite ? [] : graphite_exclusions) + webgpu_view_exclusions
if defined?(install_modules_dependencies()) != nil
install_modules_dependencies(s)Suggested fix
When react-native-wgpu is installed alongside Skia, Skia should defer to it as the canonical WebGPUView provider. This requires changes at all three levels:
- Podspec — exclude
apple/WebGPUView.mmandapple/WebGPUView.hto avoid duplicate native classes codegenConfig.ios.componentProvider— removeWebGPUViewto avoid duplicate codegen registrations- JS/TS specs — re-export from
react-native-wgpuinstead of callingcodegenNativeComponentdirectly
React Native Skia Version
2.5.4
React Native Version
0.83.4
Using New Architecture
- Enabled
Steps to Reproduce
- Clone the repro repo
npm install --legacy-peer-deps && npx install-skianpx expo prebuild --cleannpx expo run:ios
Result: Build fails at the linker stage with 3 duplicate ObjC symbols — the project cannot be built at all.
Build output:
❌ duplicate symbol '_OBJC_METACLASS_$_WebGPUView' in
┌─ libreact-native-skia.a[28](WebGPUView.o)
└─ libreact-native-wgpu.a[32](WebGPUView.o)
❌ duplicate symbol '_OBJC_CLASS_$_WebGPUView' in
┌─ libreact-native-skia.a[28](WebGPUView.o)
└─ libreact-native-wgpu.a[32](WebGPUView.o)
❌ duplicate symbol 'WebGPUViewCls()' in
┌─ libreact-native-skia.a[28](WebGPUView.o)
└─ libreact-native-wgpu.a[32](WebGPUView.o)
❌ ld: 3 duplicate symbols
❌ clang: error: linker command failed with exit code 1
Snack, Code Example, Screenshot, or Link to Repository
https://github.com/JeanDes-Code/RNSkia-dualWebGPUView-minimal-repro