Skip to main content
EaseView is a native Fabric component that brings declarative, CSS-transition-style animations to React Native using Core Animation on iOS and ObjectAnimator/SpringAnimation on Android. Animations run entirely off the JS thread — no worklets, no shared values, no JS animation loop. It works like a standard View — accepts children, styles, and all ViewProps. When values in animate change, the view smoothly transitions to the new values using native platform APIs.
import { EaseView } from 'react-native-ease';
EaseView requires React Native 0.76+ (Fabric / new architecture). It does not support the old architecture.

Usage

import { EaseView } from 'react-native-ease';

function AnimatedCard({ visible, children }) {
  return (
    <EaseView
      initialAnimate={{ opacity: 0, translateY: 20 }}
      animate={{ opacity: visible ? 1 : 0, translateY: visible ? 0 : 20 }}
      transition={{ type: 'spring', damping: 15, stiffness: 120 }}
      transformOrigin={{ x: 0.5, y: 0.5 }}
      onTransitionEnd={({ finished }) => {
        console.log('Animation finished:', finished);
      }}
      style={{ backgroundColor: 'white', borderRadius: 12, padding: 16 }}
    >
      {children}
    </EaseView>
  );
}

Props

animate
AnimateProps
Target values for animated properties. When these values change, the view animates from its current state to the new values. See AnimateProps for the full list of animatable properties.
<EaseView animate={{ opacity: 1, translateY: 0, scale: 1 }} />
initialAnimate
AnimateProps
Starting values for enter animations. On mount, the view starts at these values and animates to animate. Without initialAnimate, the view renders at the animate values immediately with no mount animation.
// Fade in and slide up on mount
<EaseView
  initialAnimate={{ opacity: 0, translateY: 20 }}
  animate={{ opacity: 1, translateY: 0 }}
/>
initialAnimate is also required when using loop on a timing transition — it defines the start value the loop returns to.
transition
Transition
Animation configuration. Controls whether the animation uses a fixed-duration timing curve, a physics-based spring, or no animation at all. Can be a single config applied to all properties, or a per-property map.Defaults to { type: 'timing', duration: 300, easing: 'easeInOut' } when omitted.See Transition for all configuration options.
// Timing
<EaseView transition={{ type: 'timing', duration: 400, easing: 'easeOut' }} />

// Spring
<EaseView transition={{ type: 'spring', damping: 15, stiffness: 120 }} />

// Per-property map
<EaseView
  transition={{
    opacity: { type: 'timing', duration: 150, easing: 'easeOut' },
    transform: { type: 'spring', damping: 12, stiffness: 200 },
  }}
/>
onTransitionEnd
(event: TransitionEndEvent) => void
Called when all running animations complete. Receives a TransitionEndEvent object.
<EaseView
  animate={{ opacity: visible ? 1 : 0 }}
  onTransitionEnd={({ finished }) => {
    if (finished) {
      console.log('Animation completed naturally');
    } else {
      console.log('Animation was interrupted');
    }
  }}
/>
transformOrigin
TransformOrigin
Pivot point for scale and rotation animations, expressed as 0–1 fractions of the view’s dimensions. Defaults to { x: 0.5, y: 0.5 } (center).
// Rotate from the top-left corner
<EaseView
  animate={{ rotate: isOpen ? 45 : 0 }}
  transformOrigin={{ x: 0, y: 0 }}
/>

// Scale from the bottom-right
<EaseView
  animate={{ scale: active ? 1.2 : 1 }}
  transformOrigin={{ x: 1, y: 1 }}
/>
useHardwareLayer
boolean
default:"false"
Android only. When true, rasterizes the view to a GPU texture for the duration of the animation. Animated property changes (opacity, scale, rotation) are then composited on the RenderThread without redrawing the view hierarchy.This is a no-op on iOS, where Core Animation already composites off the main thread.
Views with useHardwareLayer clip children that overflow their layout bounds. Avoid using this with translateX/translateY animations on views with overflowing content, as it will cause visual artifacts.
<EaseView
  animate={{ opacity: isVisible ? 1 : 0, scale: isVisible ? 1 : 0.9 }}
  useHardwareLayer
/>
style
ViewStyle
Non-animated styles — layout, colors, borders, shadows, and any other ViewStyle properties.If a property appears in both style and animate, the animated value takes priority and the style value is stripped. A dev warning is logged when this happens.
<EaseView
  animate={{ translateY: moved ? -10 : 0 }}
  style={{
    backgroundColor: 'white',
    borderRadius: 12,
    padding: 16,
    shadowColor: '#000',
  }}
/>
className
string
NativeWind / Tailwind CSS class string. Requires NativeWind to be installed and configured in your project.
<EaseView
  animate={{ opacity: visible ? 1 : 0 }}
  className="bg-white rounded-xl p-4"
/>
children
ReactNode
Child elements rendered inside the animated view.
...rest
ViewProps
All other standard React Native View props are forwarded to the underlying view (accessible, testID, pointerEvents, etc.).
  • AnimateProps — all animatable properties
  • Transition — timing, spring, and none configuration
  • Types — full TypeScript type reference

Build docs developers (and LLMs) love