Package Exports
- react-spring
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-spring) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Installation 🖥
npm install react-spring
Table of Contents 👇
- What is it?
- Why do we need yet another?
- Overview
- Render props, interpolation and native rendering
- Links
What is it? 🤔
A set of simple, spring-physics based primitives (as in building blocks) that should cover most of your UI related animation needs once plain CSS can't cope any longer. Forget easings, durations, timeouts and so on as you fluidly move data from one state to another. This isn't meant to solve each and every problem but rather to give you tools flexible enough to confidently cast ideas into moving interfaces.
Why do we need yet another? 🧐
react-spring is a cooked down fork of Christopher Chedeau's animated (which is used in react-native by default). It is trying to bridge it with Cheng Lou's react-motion. Although both are similarily spring-physics based they are still polar opposites.
Declarative | Primitives | Interpolations | Performance | |
---|---|---|---|---|
React-motion | ✅ | ✅ | ❌ | ❌ |
Animated | ❌ | ❌ | ✅ | ✅ |
React-spring | ✅ | ✅ | ✅ | ✅ |
react-spring builds upon animated's foundation, casting its imperative side out, making it leaner and more flexible. It inherits react-motions declarative api and goes to great lengths to simplify it. It has lots of useful primitives, can interpolate mostly everything and last but not least, can animate by committing directly to the dom instead of re-rendering a component frame-by-frame.
For a more detailed explanation read Why React needed yet another animation library.
Overview 🔭
Springs (Demo)

A Spring
will move data from one state to another. It remembers the current state, value changes are always fluid.
import { Spring } from 'react-spring'
<Spring from={{ opacity: 0 }} to={{ opacity: 1 }}>
{styles => <div style={styles}>i will fade in</div>}
</Spring>
Mount/unmount Transitions (Demo)

Transition
watches elements as they mount and unmount, it helps you to animate these changes.
import { Transition } from 'react-spring'
<Transition
keys={items.map(item => item.key)}
from={{ opacity: 0, height: 0 }}
enter={{ opacity: 1, height: 20 }}
leave={{ opacity: 0, height: 0 }}>
{items.map(item => styles => <li style={styles}>{item.text}</li>)}
</Transition>
2-state and 1-state Reveals (Demo)

Given a single child instead of a list you can toggle between two components.
import { Transition } from 'react-spring'
<Transition from={{ opacity: 0 }} enter={{ opacity: 1 }} leave={{ opacity: 0 }}>
{toggle ? ComponentA : ComponentB}
</Transition>
If you need to toggle a single child, that is also possible: {toggle && Component}
Trails and staggered animations (Demo)

Trail
animates the first child of a list of elements, the rest follow the spring of their previous sibling.
import { Trail } from 'react-spring'
<Trail from={{ opacity: 0 }} to={{ opacity: 1 }} keys={items.map(item => item.key)}>
{items.map(item => styles => <div style={styles}>{item.text}</div>)}
</Trail>
Parallax and page transitions (Demo)

Parallax
allows you to declaratively create page/scroll-based animations.
import { Parallax, ParallaxLayer } from 'react-spring'
<Parallax pages={2}>
<ParallaxLayer offset={0} speed={0.2}>
first Page
</ParallaxLayer>
<ParallaxLayer offset={1} speed={0.5}>
second Page
</ParallaxLayer>
</Parallax>
Time/duration-based implementations and addons (Demo)

You'll find varying implementations under /dist/addons. For now there's a time-based animation as well common easings, and IOS'es harmonic oscillator spring. All primitives understand the impl
property which you can use to switch implementations.
import { TimingAnimation, Easing } from 'react-spring/dist/addons'
<Spring impl={TimingAnimation} config={{ delay: 200, duration: 1000, easing: Easing.linear }} ...>
Keyframes (Demo)

Keyframes
allows you to create a animation primitive that reacts to predefined, named slots. Each slot can return raw-properties, arrays or async functions with side-effects. The resulting primitive can receive properties like native
or from
, etc.
import { Keyframes } from 'react-spring'
// Cou can create keyframes for springs, trails and transitions
const Container = Keyframes.Spring({
// Single props
show: { to: { opacity: 1 } },
// Array-chans
showAndHide: [ { to: { opacity: 1 } }, { to: { opacity: 0 } }],
// Functions
wiggle: async call => {
await call({ to: { x: 100 }, config: config.wobbly })
await delay(1000)
await call({ to: { x: 0 }, config: config.gentle })
}
})
// Container
<Container state="show">
{styles => <div style={styles}>Hello</div>}
</Container>
Render props, interpolation and native rendering 🚀
Render props
The Api is driven by render props (though we do expose imperative Api as well). By principle we offer both render
and children
as well as prop forwardwing (unrecognized props will be spread over the receiving component).
const Header = ({ children, bold, ...styles }) => (
<h1 style={styles}>
{bold ? <b>{children}</b> : children}
</h1>
)
<Spring render={Header} to={{ color: 'fuchsia' }} bold={this.state.bold}>
hello there
</Spring>
Interpolation
You can interpolate almost everything, from numbers, colors (names, rgb, rgba, hsl, hsla), paths (as long as the number of points match, otherwise use custom interpolation), percentages, units, arrays and string patterns:
<Spring to={{
scale: toggle ? 1 : 2,
start: toggle ? '#abc' : 'rgb(10,20,30)',
end: toggle ? 'seagreen' : 'rgba(0,0,0,0.5)',
stop: toggle ? '0%' : '50%',
rotate: toggle ? '0deg' : '45deg',
shadow: toggle ? '0 2px 2px 0px rgba(0, 0, 0, 0.12)' : '0 20px 20px 0px rgba(0, 0, 0, 0.5)',
path: toggle ? 'M20,380 L380,380 L380,380 Z' : 'M20,20 L20,380 L380,380 Z',
vector: toggle ? [1,2,50,100] : [20,30,1,-100],
}}>
Native rendering
![]() |
![]() |
---|---|
Most libs animate by having React recalculate the component-tree on every frame. Here it attempts to animate a component consisting of ~300 sub-components, plowing through the frame budget and causing jank. | React-spring with the native property renders the component only once, from then on the animation will be applied directly to the dom in a requestAnimationFrame-loop, similar to how gsap and d3 do it. |
import { Spring, animated } from 'react-spring'
<Spring native from={{ opacity: 0 }} to={{ opacity: 1 }}>
{styles => <animated.div style={styles}>i will fade in</animated.div>}
</Spring>
More about native rendering and interpolation here.
Links 🔗
Examples and Codesandboxes
Click for a combined example repository you can install as well as a collection of code-sandboxes to toy around with online.
API Overview
If you ever plan to use this library, this should be a must-read. It will go a little deeper into the primitives and how "native" rendering can make a large performance impact (for the better of course).
Full API reference
For annotated prop-types, good for finding out about all the obscure props that i don't want to bore you with (but which might come in handy, you never know).