useFollowValue
useFollowValue is the generalised follow hook. Where useSpring is locked to spring physics, useFollowValue accepts any transition type — spring, tween, inertia, or keyframes — so a single source can drive multiple followers, each with its own personality.
<script lang="ts">
import { useFollowValue, useMotionValue } from '@humanspeak/svelte-motion'
const x = useMotionValue(0)
const eased = useFollowValue(x, { type: 'tween', duration: 0.4, ease: 'easeOut' })
</script>
<button onclick={() => x.set(x.get() === 0 ? 200 : 0)}>Toggle</button>
<div style="transform: translateX({eased.current}px)">eased follow</div><script lang="ts">
import { useFollowValue, useMotionValue } from '@humanspeak/svelte-motion'
const x = useMotionValue(0)
const eased = useFollowValue(x, { type: 'tween', duration: 0.4, ease: 'easeOut' })
</script>
<button onclick={() => x.set(x.get() === 0 ? 200 : 0)}>Toggle</button>
<div style="transform: translateX({eased.current}px)">eased follow</div>Returns a real motion-dom MotionValue augmented with a $state-backed .current getter and a Svelte readable .subscribe shim — same shape every other Tier 2 hook returns.
Move your cursor over this card
- crisp spring
- bouncy spring
- floaty spring
- quick tween
- long tween
- wobbly spring
The example above drives six followers from a single source (the pointer position). Each gets a different transition — crisp spring, bouncy spring, floaty heavy spring, quick tween, long lazy tween, and a deliberately under-damped wobbly spring — so the trail visually demonstrates how each transition feels. (Inertia is shown separately in its own section — it’s the right transition for fling-and-release, not continuous follow.)
Relationship to useSpring
useSpring(source, options) is now a thin wrapper that calls useFollowValue(source, { type: 'spring', ...options }). Use whichever reads better:
// Equivalent — both produce a spring-animated MotionValue.
const a = useSpring(0, { stiffness: 200 })
const b = useFollowValue(0, { type: 'spring', stiffness: 200 })// Equivalent — both produce a spring-animated MotionValue.
const a = useSpring(0, { stiffness: 200 })
const b = useFollowValue(0, { type: 'spring', stiffness: 200 })Reach for useFollowValue when you want a non-spring transition or when you’re building something that mixes transition types (the example above is the canonical case).
Transition types
useFollowValue’s options accept any motion-dom transition shape. The four built-in types:
Spring (default)
<script lang="ts">
const target = useMotionValue(0)
// Defaults — soft spring, no overshoot.
const soft = useFollowValue(target)
// Tuned — stiff and lightly damped (bouncy).
const bouncy = useFollowValue(target, {
type: 'spring',
stiffness: 220,
damping: 14
})
// Heavy — high mass, floaty motion.
const heavy = useFollowValue(target, {
type: 'spring',
stiffness: 70,
damping: 12,
mass: 4
})
</script><script lang="ts">
const target = useMotionValue(0)
// Defaults — soft spring, no overshoot.
const soft = useFollowValue(target)
// Tuned — stiff and lightly damped (bouncy).
const bouncy = useFollowValue(target, {
type: 'spring',
stiffness: 220,
damping: 14
})
// Heavy — high mass, floaty motion.
const heavy = useFollowValue(target, {
type: 'spring',
stiffness: 70,
damping: 12,
mass: 4
})
</script>All SpringOptions are accepted: stiffness, damping, mass, velocity, restDelta, restSpeed, duration, visualDuration, bounce. See useSpring for the per-option semantics.
Tween
<script lang="ts">
const target = useMotionValue(0)
const eased = useFollowValue(target, {
type: 'tween',
duration: 0.4,
ease: 'easeOut'
})
</script><script lang="ts">
const target = useMotionValue(0)
const eased = useFollowValue(target, {
type: 'tween',
duration: 0.4,
ease: 'easeOut'
})
</script>ease accepts a string ('linear', 'easeIn', 'easeOut', 'easeInOut', 'circIn' / 'circOut' / 'circInOut', 'backIn' / 'backOut' / 'backInOut', 'anticipate'), a function (t: number) => number, or a cubic-bezier array [x1, y1, x2, y2].
Inertia
<script lang="ts">
const target = useMotionValue(0)
const settling = useFollowValue(target, {
type: 'inertia',
power: 0.6,
timeConstant: 600
})
</script><script lang="ts">
const target = useMotionValue(0)
const settling = useFollowValue(target, {
type: 'inertia',
power: 0.6,
timeConstant: 600
})
</script>inertia decays toward the target with no overshoot. Useful for scroll-rest, fling animations, and floaty-but-stable trails.
Keyframes
<script lang="ts">
const target = useMotionValue(0)
const stepped = useFollowValue(target, {
type: 'keyframes',
values: [0, 100, 50, 80, 0],
times: [0, 0.3, 0.5, 0.7, 1],
duration: 1
})
</script><script lang="ts">
const target = useMotionValue(0)
const stepped = useFollowValue(target, {
type: 'keyframes',
values: [0, 100, 50, 80, 0],
times: [0, 0.3, 0.5, 0.7, 1],
duration: 1
})
</script>Use when you want a follower that animates through a specific path on every source change rather than directly toward the new value.
With Svelte readables
Like useSpring, useFollowValue accepts a Svelte Readable as the source via an internal bridge. Useful when the source is a writable store or a hook that still returns a Svelte readable:
<script lang="ts">
import { writable } from 'svelte/store'
import { useFollowValue } from '@humanspeak/svelte-motion'
const target = writable(0)
const eased = useFollowValue(target, { type: 'tween', duration: 0.3 })
</script>
<button onclick={() => target.set(200)}>set 200</button>
<div style="transform: translateX({eased.current}px)" /><script lang="ts">
import { writable } from 'svelte/store'
import { useFollowValue } from '@humanspeak/svelte-motion'
const target = writable(0)
const eased = useFollowValue(target, { type: 'tween', duration: 0.3 })
</script>
<button onclick={() => target.set(200)}>set 200</button>
<div style="transform: translateX({eased.current}px)" />SSR
useFollowValue is SSR-safe. On the server it returns a static MotionValue with no animation; .set and .jump become no-ops so the initial value matches the server-rendered snapshot.
API Reference
Parameters
- source
number | string | MotionValue<T> | Readable<T>— initial value or a source to follow. - options
UseFollowValueOptions(optional) —ValueAnimationTransitionof any type (spring/tween/inertia/keyframes) plusskipInitialAnimationto suppress the first animation when following a hot source (useful foruseScroll-restoration scenarios).
Returns
A FollowMotionValue<T> — a real motion-dom MotionValue (composes with useTransform, useVelocity, animate(), etc.) plus:
.current— Svelte 5 reactive getter (templates /$derived/$effect)..get()— imperative current-value read..set(v)— animate towardvusing the configured transition..jump(v)— set immediately without animation..subscribe(run)— Svelte readable store contract..on(event, cb)— motion-dom event bus ('change','animationStart','animationComplete').- All other
MotionValuemethods.
See also
useSpring— convenience wrapper withtype: 'spring'baked inuseMotionValue— the base motion-value primitive (no follow / no animation)- Motion values overview — how the augmented MotionValue shape composes
Based on Motion’s useFollowValue API.