The component API mirrors react-native-skia — Canvas, shapes, declarative paints, Path2D — so an RN-Skia scene ports to Lynx mostly by changing the import. Powered by the skity GPU backend: one C++ renderer drives Android (OpenGL ES / Vulkan) and iOS (Metal), with zero JS per frame animations on the render thread.
That's the idea. scumble tracks the react-native-skia component API (baseline 2.11.0) — the same <Canvas> / shape / <Paint> / gradient / filter names and props, the Canvas-style Path2D, image and paragraph components — so an RN-Skia scene ports to Lynx mostly by changing the import. Feature-by-feature status lives in FEATURE_PARITY.md (geometry ~95%, paint ~90%, text ~85%).
Where it deliberately differs: rendering rides the skity GPU backend (not Skia) through a FlatBuffer command stream — no JSI imperative object surface — and animation is built in rather than delegated to reanimated. skity is also far leaner — ~90K lines of C++, roughly a tenth of Skia — which keeps scumble's whole native APK footprint under a third of react-native-skia's, at 90–95% feature parity. See the comparison.
An animation engine that lives on the render thread
Declare a track once; a per-vsync tick on the render thread interpolates every frame and a stop-on-idle driver powers down when nothing is playing. Playback control comes with it — pause, seek, and completion callbacks without a single extra frame of JS.