`createMemo`

Creates a cached derived value. Recomputes only when its dependencies change.

import { createMemo } from '@barefootjs/dom'

const getter = createMemo<T>(fn: () => T): () => T

Returns a read-only getter function.

#Basic Usage

const [count, setCount] = createSignal(2)
const doubled = createMemo(() => count() * 2)

doubled() // 4
setCount(5)
doubled() // 10

#When to Use

Use createMemo when you have a derived value that:

  • Depends on one or more signals
  • Is used in multiple places (avoids recalculating)
  • Involves a non-trivial computation
const [todos, setTodos] = createSignal<Todo[]>([])
const [filter, setFilter] = createSignal<'all' | 'active' | 'done'>('all')

const filteredTodos = createMemo(() => {
  const list = todos()
  switch (filter()) {
    case 'active': return list.filter(t => !t.done)
    case 'done':   return list.filter(t => t.done)
    default:       return list
  }
})

// Used in multiple effects and JSX expressions
createEffect(() => console.log(filteredTodos().length))

For simple expressions used only once, a memo is not necessary — the signal getter in JSX is sufficient:

// No memo needed
<p>{count() * 2}</p>

#Chaining Memos

Memos can depend on other memos:

const [count, setCount] = createSignal(1)
const doubled = createMemo(() => count() * 2)
const quadrupled = createMemo(() => doubled() * 2)

createEffect(() => {
  console.log(quadrupled()) // 4
})

setCount(3) // Logs: 12 (3 → 6 → 12)

Each memo in the chain only recomputes when its direct dependencies change.

#Memo vs Effect

createMemo createEffect
Returns a value Yes (getter function) No
Triggers other effects Yes (acts as a signal) No
Used for Derived data Side effects (DOM, fetch, logging)

Internally, createMemo is sugar over createSignal + createEffect — it creates a signal and an effect that updates it when dependencies change. This means a memo behaves exactly like a read-only signal to the rest of the reactive system.