Skip to content

Physics-level spring coupling #2542

@joshuaellis

Description

@joshuaellis

A clear and concise description of what the feature is

Let springs couple at the physics level, not just by target value. A spring's target can already follow another spring through the FluidValue observer model (useTrail is built on it), but its physics are fixed — config is SpringConfig | ((key) => SpringConfig), resolved once per update via mergeConfig (packages/core/src/types/props.ts:256). This makes the physics reactive: a spring's config (tension/friction/mass) can depend on another spring's live value.

const { open } = useSpring(() => ({ open: 0 }))
const { panel } = useSpring(() => ({
  panel: open,                                       // target-following — ships today
  config: { tension: open.to(o => 100 + o * 200) },  // reactive physics — new
}))
// `open.to(...)` is already a FluidValue; what's new is `config` accepting one.

Why should this feature be included?

Value-level following already ships, so it isn't a differentiator. Physics-level coupling is — it's only possible because react-spring runs a real simulation; there's nothing to couple in a keyframe engine. It unlocks effects you can't express today: stiffness that reacts to a neighbour's position, drag that stiffens its followers, and mutually-reacting springs.

Scope / non-goals

  • Value-level target following already ships (FluidValue, useTrail) — not in scope.
  • Core work: widen config to accept reactive/fluid inputs. This is additive — existing static configs are unaffected, so it isn't a breaking change.
  • Extensions (separate, and the only breaking part): coupling on another spring's velocity would mean exposing SpringValue.velocity reactively (today it's a number snapshot), and bidirectional coupling needs cycle handling in the observer graph.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: corerelates to core classes // parts of the librarykind: requestNew feature or request that should be actioned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions