Docs/Primitives/createComputed

createComputed

createComputed is the motion-value version of createMemo: it tracks .get() calls inside the getter and writes the derived result into a new MotionValue. It exists because MotionValues live outside Solid's reactive graph — they update on motion's frameloop, so a createMemo reading .get() would never re-run. createTransform(fn) is the canonical form of this primitive (it matches motion/react's useTransform(fn)); createComputed is the same thing under a motion-value-centric name.

Two things to keep in mind:

  • Name clash: solid-js exports an unrelated createComputed (an eager reactive computation that returns nothing). Make sure your import comes from motion-solidjs, especially with auto-imports.
  • When not to use it: if the computation only reads Solid signals and the result feeds plain JSX, use createMemo — reach for createComputed/createTransform(fn) only when MotionValues are on the input or output side.
import { createComputed, createMotionValue } from 'motion-solidjs'

const a = createMotionValue(0)
const b = createMotionValue(0)
const product = createComputed(() => a.get() * b.get())
createComputed
distance = 0.0
create-computed.tsxOpen ↗
import {
  motion,
  createComputed,
  createMotionValue,
  createMotionValueEvent,
  createTransform,
} from 'motion-solidjs'
import { createSignal } from 'solid-js'

export const meta = {
  slug: 'create-computed',
  title: 'createComputed',
  category: 'motion-values',
  description: 'Derive a motion value from a getter — dependencies are auto-tracked.',
  tag: 'createComputed',
} as const

export default function UseComputedExample() {
  const x = createMotionValue(0)
  const y = createMotionValue(0)

  // Each `.get()` inside the getter is auto-collected as a dependency.
  // `distance` updates whenever either source changes — no manual subscribe.
  const distance = createComputed(() => Math.hypot(x.get(), y.get()))

  // Pipe the derived motion value into ordinary transforms.
  const scale = createTransform(distance, [0, 140], [1, 1.8], { clamp: true })
  const bg = createTransform(distance, [0, 140], ['#7c5cff', '#ff4d8d'], { clamp: true })

  // Mirror the derived value into a signal for the text readout.
  const [readout, setReadout] = createSignal('0.0')
  createMotionValueEvent(distance, 'change', (d) => setReadout(d.toFixed(1)))

  return (
    <div class="flex flex-col items-center gap-4">
      <div class="relative grid h-56 w-56 place-items-center rounded-3xl border border-border bg-card">
        <motion.div
          drag
          dragConstraints={{ left: -90, right: 90, top: -90, bottom: 90 }}
          dragElastic={0.05}
          dragMomentum={false}
          style={{ x, y, 'background-color': bg, scale }}
          class="h-12 w-12 cursor-grab rounded-full shadow-glow active:cursor-grabbing"
        />
      </div>
      <div class="font-mono text-xs tabular-nums text-fg-muted">
        distance = <span class="text-fg">{readout()}</span>
      </div>
    </div>
  )
}