Our imperative API. You can initialise it via function call, or for better practice use the hook useSpringRef. For more contextual information for this function and why it's so important, see here.



import { animated, useSpring, useSpringRef } from '@react-spring/web'
function MyComponent() {
const api = useSpringRef()
const props = useSpring({
ref: api,
from: { opacity: 0 },
to: { opacity: 1 },
return <animated.div style={props}>Hello World</animated.div>

Function call

import { Component, createRef } from 'react'
import { Controller, animated, SpringRef } from '@react-spring/web'
class AnimatedComponent extends Component {
isShowing = createRef(false)
api = SpringRef()
animations = new Controller({ opacity: 0, ref: this.api })
toggle = () => {
this.animations.start({ opacity: this.isShowing ? 1 : 0 })
this.isShowing = !this.isShowing
render() {
return (
<button onClick={this.toggle}>click</button>
<animated.div style={this.animations.springs}>I will fade</animated.div>





Add a controller to this ref.

add(ctrl: Controller<State>): void


Remove a controller from this ref.

delete(ctrl: Controller<State>): void


Pause some or all animations by passing SpringValue keys.

pause(): this
pause(keys: OneOrMore<string>): this
pause(keys?: OneOrMore<string>): this


Resume some or all animations by passing SpringValue keys.

resume(): this
resume(keys: OneOrMore<string>): this
resume(keys?: OneOrMore<string>): this


Update the state of each controller without animating. Accepts either a partial state object or a function that returns a partial state object.

set(values: Partial<State>): void
set(values: (index: number, ctrl: Controller<State>) => Partial<State>): void


Start the queued animations of each controller. Alternatively pass a ControllerUpdate object to update the state of each controller before starting the animations. Or pass a function to edit the ControllerUpdate depending on the specific Controller.

start(): AsyncResult<Controller<State>>[]
start(props: ControllerUpdate<State>): AsyncResult<Controller<State>>[]
start(props: ControllerUpdateFn<State>): AsyncResult<Controller<State>>[]
props?: ControllerUpdate<State> | ControllerUpdateFn<State>
): AsyncResult<Controller<State>>[]


Stop some or all of the animations by passing SpringValue keys. Additionall, cancel those animations by passing a boolean as the first argument and the keys as the second.

stop(): this
stop(keys: OneOrMore<string>): this
stop(cancel: boolean): this
stop(cancel: boolean, keys: OneOrMore<string>): this
stop(keys?: OneOrMore<string>): this
stop(cancel: boolean, keys?: OneOrMore<string>): this


Add the same props to each controller's update queue. Or alternatively generate separate props for each controller's update queue with a function.

update(props: ControllerUpdate<State>): this
update(props: ControllerUpdateFn<State>): this
update(props: ControllerUpdate<State> | ControllerUpdateFn<State>): this