reanimated-skia-performance

Write and review high-performance React Native animations and 2D graphics using react-native-reanimated (v4+) and @shopify/react-native-skia (Canvas scenes, runtime effects/shaders). Use for: gesture-driven interactions, spring/timing transitions, layout/mount animations, Reanimated CSS transitions/animations, Skia drawings, animated shader uniforms, path/vector interpolation, dev-mode tuning panels (sliders), and diagnosing animation jank (JS thread stalls, excessive re-renders, per-frame allocations).

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "reanimated-skia-performance" with this command: npx skills add andreev-danila/skills/andreev-danila-skills-reanimated-skia-performance

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() over shared.value in app code (React Compiler friendly).
  • Minimize JS↔UI crossings: avoid scheduleOnRN/runOnJS except for unavoidable side effects.
  • For Skia, avoid per-frame React renders: pass SharedValues directly to Skia props/uniforms.

Workflow

  1. Define the effect: what animates, duration/curve, interrupt rules, and gesture input.
  2. Choose the renderer:
    • Use Reanimated styles for transforms/opacity/layout.
    • Use Skia for custom drawing, particles, gradients, runtime effects/shaders.
  3. Choose the primitive:
    • Use Reanimated CSS transitions/animations for simple declarative style changes.
    • Use withTiming for tweens, withSpring for physics, withDecay for momentum.
    • Use Layout Animations for mount/unmount or layout changes.
  4. Implement a single data flow on the UI thread (no setState per frame).
  5. Do a perf pass (see references/perf-checklist.md).

Patterns

Shared values (React Compiler safe)

  • Read: progress.get()
  • Write: progress.set(withTiming(1))
import { useEffect } from 'react';
import { useSharedValue, withTiming } from 'react-native-reanimated';

const progress = useSharedValue(0);

useEffect(() => {
  progress.set(withTiming(1, { duration: 400 }));
}, [progress]);

Reanimated v4 CSS transitions

Use for state-driven style changes where you do not need bespoke worklets.

import Animated from 'react-native-reanimated';

<Animated.View
  style={{
    width: expanded ? 240 : 160,
    opacity: enabled ? 1 : 0.6,
    transitionProperty: ['width', 'opacity'],
    transitionDuration: 220,
    transitionTimingFunction: 'ease-in-out',
  }}
/>

Reanimated v4 CSS animations (keyframes)

Use for keyframe-like sequences (pulses, wiggles, repeated loops) without writing custom worklets.

Supported settings:

  • animationName (keyframes object)
  • animationDuration
  • animationDelay
  • animationTimingFunction
  • animationDirection
  • animationIterationCount
  • animationFillMode
  • animationPlayState
import Animated from 'react-native-reanimated';

const pulse = {
  from: { transform: [{ scale: 1 }], opacity: 0.9 },
  '50%': { transform: [{ scale: 1.06 }], opacity: 1 },
  to: { transform: [{ scale: 1 }], opacity: 0.9 },
};

<Animated.View
  style={{
    animationName: pulse,
    animationDuration: '900ms',
    animationDelay: '80ms',
    animationTimingFunction: 'ease-in-out',
    animationDirection: 'alternate',
    animationIterationCount: 'infinite',
    animationFillMode: 'both',
    animationPlayState: paused ? 'paused' : 'running',
  }}
/>

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 via useDerivedValue.
  • 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.

import { Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';

const x = useSharedValue(0);
const gesture = Gesture.Pan()
  .onUpdate((e) => {
    x.set(e.translationX);
  })
  .onEnd(() => {
    x.set(withSpring(0));
  });

const style = useAnimatedStyle(() => ({ transform: [{ translateX: x.get() }] }));

<GestureDetector gesture={gesture}>
  <Animated.View style={style} />
</GestureDetector>;

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 .value in your app code; pass the SharedValue object.
import { useMemo } from 'react';
import { Skia, Canvas, Fill, Paint, Shader, type Uniforms } from '@shopify/react-native-skia';
import { useDerivedValue } from 'react-native-reanimated';
import { useClock } from '@shopify/react-native-skia';

const sksl = `
uniform float2 u_resolution;
uniform float u_time;

half4 main(float2 xy) {
  float2 uv = xy / u_resolution;
  float v = 0.5 + 0.5 * sin(u_time * 0.002 + uv.x * 8.0);
  return half4(v, v * 0.6, 1.0 - v, 1.0);
}
`;

const effect = useMemo(() => Skia.RuntimeEffect.Make(sksl), []);
if (!effect) return null;

const clock = useClock(); // ms since first frame
const uniforms = useDerivedValue<Uniforms>(() => ({
  u_resolution: Skia.Point(width, height),
  u_time: clock.get(),
}));

<Canvas style={{ width, height }}>
  <Fill>
    <Paint>
      <Shader source={effect} uniforms={uniforms} />
    </Paint>
  </Fill>
</Canvas>;

Common pitfalls

  • Do not read shared values in React render; read them in worklets (useAnimatedStyle, useDerivedValue).
  • Do not call runOnJS/scheduleOnRN in onUpdate unless 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

Self Updater

⭐ OPEN SOURCE! GitHub: github.com/GhostDragon124/openclaw-self-updater ⭐ ONLY skill with Cron-aware + Idle detection! Auto-updates OpenClaw core & skills, an...

Registry SourceRecently Updated
1171Profile unavailable
Coding

ClawHub CLI Assistant

Use the ClawHub CLI to publish, inspect, version, update, sync, and troubleshoot OpenClaw skills from the terminal.

Registry SourceRecently Updated
1.9K2Profile unavailable
Coding

SkillTree Learning Progress Tracker

Track learning across topics like an RPG skill tree. Prerequisites, milestones, suggested next steps. Gamified learning path.

Registry SourceRecently Updated
900Profile unavailable
Coding

Speak Turbo - Talk to your Claude 90ms latency!

Give your agent the ability to speak to you real-time. Talk to your Claude! Ultra-fast TTS, text-to-speech, voice synthesis, audio output with ~90ms latency....

Registry SourceRecently Updated
4480Profile unavailable