Unlock experimental Skia–WebGPU graphics on Apple platforms — and make path-heavy scenes dramatically faster.
An experimental, reproducible setup helper for running React Native Skia with its Graphite backend on iOS and macOS. It handles the installation details that otherwise make a project silently build Ganesh binaries under Graphite flags, and documents a benchmark protocol you can run against your own scenes.
Graphite is not a universal performance switch. Our A15 measurements show a strong, mechanism-backed win for many stroked paths, while fragment shaders, glyphs, blur, and batched rounded rectangles were already display-limited on both backends. The chart shows minimum gains: Graphite hit the refresh ceiling, so exact throughput beyond that point was not measured.
| What you need | What Graphite can offer |
|---|---|
| Path-heavy geometry | At least 6.0× faster in the measured A15 path scene; at a heavier load, at least 27.8× faster. |
| One visual layer spanning Skia and WebGPU | A shared Dawn device enables zero-copy texture interop, so Skia can sample a WebGPU-rendered texture. |
| A general frame-rate boost | Not promised. The other measured steady-state scenes showed no measurable difference. |
See the full benchmark results, including the mixed warmup result and methodology.
Use this toolkit when you need either of these capabilities:
| You are building… | Why Graphite is worth evaluating |
|---|---|
| Dense vector geometry, maps, diagrams, or animated stroked paths | The tested path workload fell from 50.07 ms to at most 8.33 ms on an A15. |
| A Skia effect over WebGPU content | Shared Dawn enables a zero-copy texture handoff instead of a CPU readback. |
Do not adopt it solely for ordinary SkSL, text, blur, or rounded-rectangle work; the measured steady-state results were already refresh-limited on Ganesh.
@shopify/react-native-skia 2.11.x, react-native-webgpu 0.8.x, and the matching react-native-skia-graphite-apple-* binary packages.Install this toolkit from GitHub in your React Native project:
npm install --save-dev github:numan98/react-native-skia-graphite
Then install the matching runtime packages:
npm install @shopify/react-native-skia@2.11 react-native-webgpu@0.8 \
react-native-skia-graphite-apple-ios@152 \
react-native-skia-graphite-apple-macos@152
Run the provided command after every install:
{
"scripts": {
"postinstall": "rnskia-graphite",
"verify:graphite": "rnskia-graphite --verify"
}
}
Then reinstall pods and build a Release app:
npm install
cd ios && pod install && cd ..
The script:
libs/.graphite marker.Give an agent the repository’s AGENTS.md alongside this README. Its shortest safe loop in a consumer project is:
npm install
cd ios && pod install && cd ..
npm run verify:graphite
verify:graphite makes no changes. It checks the selected backend markers and verifies that the installed iOS Skia binary matches the Graphite package, giving an agent a concrete pass/fail signal before it builds or benchmarks.
Do not trust package names alone. Confirm all three after pod install:
grep -o 'SK_GRAPHITE=1\|SK_GANESH=1' ios/Pods/Target\ Support\ Files/React-native-skia/*.xcconfig | sort -u
test -f node_modules/@shopify/react-native-skia/libs/.graphite
cmp node_modules/react-native-skia-graphite-apple-ios/libs/libskia.xcframework/ios-arm64/libskia.a \
node_modules/@shopify/react-native-skia/libs/ios/libskia.xcframework/ios-arm64/libskia.a
You want SK_GRAPHITE=1, no SK_GANESH=1, the marker present, and cmp to exit successfully.
Profile representative path, shader, text, and layer workloads on a physical device. Use a deterministic scene, discard and separately report warmup, alternate Ganesh and Graphite captures to control thermal drift, and do not compare battery use unless both backends draw the same content at the same rate.
The figures in this repository are a useful signal, not a promise for unrelated rendering work.
MIT. See LICENSE.
See CONTRIBUTING.md and SECURITY.md.
6 commits
JavaScript
100.0%
Unlock experimental Skia–WebGPU graphics on Apple platforms — and make path-heavy scenes dramatically faster.
An experimental, reproducible setup helper for running React Native Skia with its Graphite backend on iOS and macOS. It handles the installation details that otherwise make a project silently build Ganesh binaries under Graphite flags, and documents a benchmark protocol you can run against your own scenes.
Graphite is not a universal performance switch. Our A15 measurements show a strong, mechanism-backed win for many stroked paths, while fragment shaders, glyphs, blur, and batched rounded rectangles were already display-limited on both backends. The chart shows minimum gains: Graphite hit the refresh ceiling, so exact throughput beyond that point was not measured.
| What you need | What Graphite can offer |
|---|---|
| Path-heavy geometry | At least 6.0× faster in the measured A15 path scene; at a heavier load, at least 27.8× faster. |
| One visual layer spanning Skia and WebGPU | A shared Dawn device enables zero-copy texture interop, so Skia can sample a WebGPU-rendered texture. |
| A general frame-rate boost | Not promised. The other measured steady-state scenes showed no measurable difference. |
See the full benchmark results, including the mixed warmup result and methodology.
Use this toolkit when you need either of these capabilities:
| You are building… | Why Graphite is worth evaluating |
|---|---|
| Dense vector geometry, maps, diagrams, or animated stroked paths | The tested path workload fell from 50.07 ms to at most 8.33 ms on an A15. |
| A Skia effect over WebGPU content | Shared Dawn enables a zero-copy texture handoff instead of a CPU readback. |
Do not adopt it solely for ordinary SkSL, text, blur, or rounded-rectangle work; the measured steady-state results were already refresh-limited on Ganesh.
@shopify/react-native-skia 2.11.x, react-native-webgpu 0.8.x, and the matching react-native-skia-graphite-apple-* binary packages.Install this toolkit from GitHub in your React Native project:
npm install --save-dev github:numan98/react-native-skia-graphite
Then install the matching runtime packages:
npm install @shopify/react-native-skia@2.11 react-native-webgpu@0.8 \
react-native-skia-graphite-apple-ios@152 \
react-native-skia-graphite-apple-macos@152
Run the provided command after every install:
{
"scripts": {
"postinstall": "rnskia-graphite",
"verify:graphite": "rnskia-graphite --verify"
}
}
Then reinstall pods and build a Release app:
npm install
cd ios && pod install && cd ..
The script:
libs/.graphite marker.Give an agent the repository’s AGENTS.md alongside this README. Its shortest safe loop in a consumer project is:
npm install
cd ios && pod install && cd ..
npm run verify:graphite
verify:graphite makes no changes. It checks the selected backend markers and verifies that the installed iOS Skia binary matches the Graphite package, giving an agent a concrete pass/fail signal before it builds or benchmarks.
Do not trust package names alone. Confirm all three after pod install:
grep -o 'SK_GRAPHITE=1\|SK_GANESH=1' ios/Pods/Target\ Support\ Files/React-native-skia/*.xcconfig | sort -u
test -f node_modules/@shopify/react-native-skia/libs/.graphite
cmp node_modules/react-native-skia-graphite-apple-ios/libs/libskia.xcframework/ios-arm64/libskia.a \
node_modules/@shopify/react-native-skia/libs/ios/libskia.xcframework/ios-arm64/libskia.a
You want SK_GRAPHITE=1, no SK_GANESH=1, the marker present, and cmp to exit successfully.
Profile representative path, shader, text, and layer workloads on a physical device. Use a deterministic scene, discard and separately report warmup, alternate Ganesh and Graphite captures to control thermal drift, and do not compare battery use unless both backends draw the same content at the same rate.
The figures in this repository are a useful signal, not a promise for unrelated rendering work.
MIT. See LICENSE.
See CONTRIBUTING.md and SECURITY.md.
6 commits
JavaScript
100.0%