numan98/react-native-skia-graphite

Experimental Graphite enablement and benchmarks for React Native Skia on Apple platforms

1

stars

6

commits

JavaScript

primary language

Aug 23, 2026

updated

benchmark
graphite
ios
macos
react-native
react-native-skia
webgpu

README

React Native Skia Graphite Toolkit

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.

Status: experimental Apple platforms MIT license

A direct Ganesh versus Graphite comparison: Graphite reaches at most 8.33 milliseconds on iPhone 13 Pro path scenes versus Ganesh at 50.07 and 231.55 milliseconds, and at most 16.67 milliseconds on the simulator versus Ganesh at 50.08 and 229.75 milliseconds.

Why this exists

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 needWhat Graphite can offer
Path-heavy geometryAt 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 WebGPUA shared Dawn device enables zero-copy texture interop, so Skia can sample a WebGPU-rendered texture.
A general frame-rate boostNot promised. The other measured steady-state scenes showed no measurable difference.

See the full benchmark results, including the mixed warmup result and methodology.

The 60-second decision

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 pathsThe tested path workload fell from 50.07 ms to at most 8.33 ms on an A15.
A Skia effect over WebGPU contentShared 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.

Before you start

  • Experimental, Apple-only tooling. Treat this as a controlled integration, not a drop-in production dependency.
  • It targets @shopify/react-native-skia 2.11.x, react-native-webgpu 0.8.x, and the matching react-native-skia-graphite-apple-* binary packages.
  • Graphite and WebGPU must resolve to the same Dawn milestone. This script writes the marker used by the Skia podspec so that mismatch fails loudly at pod installation.
  • Keep a Ganesh build in CI or on a release branch until you have profiled your own app and visually checked colour output.

Install

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:

  1. Arms Graphite by writing Skia’s required libs/.graphite marker.
  2. Derives and writes the matching Dawn milestone.
  3. Stages the private Dawn and Skia headers currently missing from the published npm packages.
  4. Clears the binary-copy stamps whenever the backend changes, preventing a stale Ganesh/Graphite binary mismatch.
  5. Pins and SHA-256 verifies the one Dawn header absent from the released header bundle.

For coding agents

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.

Verify the backend

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.

Benchmark your app, not ours

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.

Known limitations

  • The current helper downloads headers during installation; it is deliberately explicit about that supply-chain cost.
  • The Dawn header archive and the missing Apple Dawn header are pinned and SHA-256 verified. Both should be reviewed whenever Skia or the Graphite binaries change.
  • Graphite’s display colour path may differ from Ganesh on wide-gamut Apple panels. Perform visual QA before shipping.
  • This repository does not bundle Skia, Dawn, or Apple binaries. Their upstream licences continue to apply.

Licence

MIT. See LICENSE.

Contributing and security

See CONTRIBUTING.md and SECURITY.md.

Contributors

numan98

6 commits

numan98/react-native-skia-graphite

Experimental Graphite enablement and benchmarks for React Native Skia on Apple platforms

1

stars

6

commits

JavaScript

primary language

Aug 23, 2026

updated

benchmark
graphite
ios
macos
react-native
react-native-skia
webgpu

README

React Native Skia Graphite Toolkit

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.

Status: experimental Apple platforms MIT license

A direct Ganesh versus Graphite comparison: Graphite reaches at most 8.33 milliseconds on iPhone 13 Pro path scenes versus Ganesh at 50.07 and 231.55 milliseconds, and at most 16.67 milliseconds on the simulator versus Ganesh at 50.08 and 229.75 milliseconds.

Why this exists

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 needWhat Graphite can offer
Path-heavy geometryAt 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 WebGPUA shared Dawn device enables zero-copy texture interop, so Skia can sample a WebGPU-rendered texture.
A general frame-rate boostNot promised. The other measured steady-state scenes showed no measurable difference.

See the full benchmark results, including the mixed warmup result and methodology.

The 60-second decision

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 pathsThe tested path workload fell from 50.07 ms to at most 8.33 ms on an A15.
A Skia effect over WebGPU contentShared 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.

Before you start

  • Experimental, Apple-only tooling. Treat this as a controlled integration, not a drop-in production dependency.
  • It targets @shopify/react-native-skia 2.11.x, react-native-webgpu 0.8.x, and the matching react-native-skia-graphite-apple-* binary packages.
  • Graphite and WebGPU must resolve to the same Dawn milestone. This script writes the marker used by the Skia podspec so that mismatch fails loudly at pod installation.
  • Keep a Ganesh build in CI or on a release branch until you have profiled your own app and visually checked colour output.

Install

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:

  1. Arms Graphite by writing Skia’s required libs/.graphite marker.
  2. Derives and writes the matching Dawn milestone.
  3. Stages the private Dawn and Skia headers currently missing from the published npm packages.
  4. Clears the binary-copy stamps whenever the backend changes, preventing a stale Ganesh/Graphite binary mismatch.
  5. Pins and SHA-256 verifies the one Dawn header absent from the released header bundle.

For coding agents

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.

Verify the backend

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.

Benchmark your app, not ours

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.

Known limitations

  • The current helper downloads headers during installation; it is deliberately explicit about that supply-chain cost.
  • The Dawn header archive and the missing Apple Dawn header are pinned and SHA-256 verified. Both should be reviewed whenever Skia or the Graphite binaries change.
  • Graphite’s display colour path may differ from Ganesh on wide-gamut Apple panels. Perform visual QA before shipping.
  • This repository does not bundle Skia, Dawn, or Apple binaries. Their upstream licences continue to apply.

Licence

MIT. See LICENSE.

Contributing and security

See CONTRIBUTING.md and SECURITY.md.

Contributors

numan98

6 commits

Languages

JavaScript

100.0%