Reanimated + Skia Performance
Defaults
- Keep animation state on the UI thread:
useSharedValue,useDerivedValue, worklets. - Prefer Reanimated v4 declarative APIs; avoid legacy
Animated. - Prefer
shared.get()/shared.set()overshared.valuein app code (React Compiler friendly). - Minimize JS↔UI crossings: avoid
scheduleOnRN/runOnJSexcept for unavoidable side effects. - For Skia, avoid per-frame React renders: pass
SharedValues directly to Skia props/uniforms.
Workflow
- Define the effect: what animates, duration/curve, interrupt rules, and gesture input.
- Choose the renderer:
- Use Reanimated styles for transforms/opacity/layout.
- Use Skia for custom drawing, particles, gradients, runtime effects/shaders.
- Choose the primitive:
- Use Reanimated CSS transitions/animations for simple declarative style changes.
- Use
withTimingfor tweens,withSpringfor physics,withDecayfor momentum. - Use Layout Animations for mount/unmount or layout changes.
- Implement a single data flow on the UI thread (no
setStateper frame). - Do a perf pass (see
references/perf-checklist.md).
Patterns
Shared values (React Compiler safe)
- Read:
progress.get() - Write:
progress.set(withTiming(1))
Reanimated v4 CSS transitions
Use for state-driven style changes where you do not need bespoke worklets.
Reanimated v4 CSS animations (keyframes)
Use for keyframe-like sequences (pulses, wiggles, repeated loops) without writing custom worklets.
Supported settings:
animationName(keyframes object)animationDurationanimationDelayanimationTimingFunctionanimationDirectionanimationIterationCountanimationFillModeanimationPlayState
Dev-mode tuning panel (sliders)
Use sliders to tune animation configs or shader uniforms in __DEV__.
- Keep the tuning UI in a separate component to avoid re-rendering the animated scene.
- Write slider values into
SharedValues via.set(). - For shader tuning: feed
SharedValues into uniforms viauseDerivedValue. - For animation config tuning: store config params in
SharedValues and read them when starting/restarting the animation.
See: references/dev-tuning.md.
Gesture-driven animation (Gesture Builder API)
Update shared values in onUpdate and drive visuals via animated styles.
Skia shader with animated uniforms
- Compile the runtime effect once (
useMemo). - Pass uniforms as a
SharedValue<Uniforms>(Skia detects animated props by{ value: T }). - Do not access
.valuein your app code; pass theSharedValueobject.
Common pitfalls
- Do not read shared values in React render; read them in worklets (
useAnimatedStyle,useDerivedValue). - Do not call
runOnJS/scheduleOnRNinonUpdateunless you must. - Do not allocate big arrays/paths/images per frame; memoize Skia objects and update via animated props.
- For runtime effects, always provide every uniform declared in the shader; missing uniforms throw.
References
- Reanimated v4 patterns and repo conventions:
references/reanimated-v4.md - Skia Canvas + runtime effects/shaders patterns:
references/skia-shaders.md - Dev-mode tuning panels (sliders):
references/dev-tuning.md - Performance checklist + debugging:
references/perf-checklist.md


