Memoize Derived Values in SolidJS with createMemo
Use createMemo to cache derived values in SolidJS so they recompute only when tracked dependencies change.
01 Nov 2026, 03:06 UTC

A derived value that runs more than it should
SolidJS components run once. After the initial render, SolidJS updates the DOM fine-grained: only the JSX expressions that read a changed signal re-execute. The problem appears when you write a derived calculation directly in JSX and read it in more than one place. Each read re-runs the calculation whenever a dependency changes, so the same work can happen multiple times per update.
Imagine a task list that shows an incomplete-task count in a summary line and uses the same count to disable a "Mark all done" button. Without a memo, the filter-and-length calculation runs once for the paragraph and again for the button every time the tasks signal changes.
What createMemo does
createMemo returns a read-only signal that caches a derived value. The function you pass does not run when the memo is created; it runs lazily on the first read. While it runs, SolidJS automatically tracks every signal you read inside the function. Those signals become the memo’s dependencies. On later reads, the memo returns the cached value until one of those dependencies changes, at which point it recomputes once.
There is no dependency array. SolidJS infers dependencies from signal access. Because the memo is read-only, you cannot assign to it directly; you update the signals it reads instead. createMemo is for pure derivations only. Do not write to the DOM, send analytics, or start subscriptions inside it; use createEffect for side effects.
Worked example: filter and count
This component filters tasks and counts incomplete ones. The count is read twice: once in a paragraph and once to disable a button.
import { createSignal, createMemo, For } from "solid-js";
function TaskList() {
const [tasks, setTasks] = createSignal([
{ id: 1, title: "Write docs", done: false },
{ id: 2, title: "Review PR", done: true },
{ id: 3, title: "Deploy site", done: false },
]);
const [filter, setFilter] = createSignal("all");
const filtered = createMemo(() => {
return tasks().filter((task) => {
if (filter() === "all") return true;
return task.done === (filter() === "done");
});
});
const incompleteCount = createMemo(() => {
return tasks().filter((task) => !task.done).length;
});
return (
setFilter("all")}>All
setFilter("done")}>Done
Incomplete: {incompleteCount()}
Mark all done
{(task) => {task.title} }
);
}
incompleteCount reads only tasks, so switching the filter recomputes filtered but not incompleteCount. Completing or adding a task changes tasks, so both memos recompute.
Verify the behavior
- Add a
console.logat the top of each memo function. - Open your browser’s developer console.
- Click "All" and "Done" repeatedly. Expect the filtered-list log, but not the incomplete-count log.
- Mark a task done or add a task. Expect both logs.
- Confirm that reading
incompleteCount()in two JSX expressions still produces only one log entry per change totasks.
Trade-offs and limits
- Overhead. Memoization tracks dependencies and stores a cached value. Wrapping a trivial calculation can cost more than it saves. Start with a plain derivation and add
createMemoonly when the value is read multiple times or the calculation is measurably expensive. - No deep tracking. SolidJS tracks signal access, not deep immutability. If you mutate an object or array read inside a memo without replacing the signal value, the memo may not recompute. Replace reactive values with their setter rather than mutating in place.
- Owner scope. Memos created inside a component are bound to that component’s owner and are disposed when the component unmounts. Memos created outside an owner scope are not tied to a component lifecycle and will not be disposed automatically when a component unmounts, which can retain memory.
- Pure derivations only. Side effects inside a memo break the reactive contract. Use
createEffectfor DOM writes, analytics, or subscriptions.
Check your SolidJS version
These notes assume stable SolidJS 1.x. Behavior in pre-release or future versions may differ. Run this in your project root to confirm the installed version:
# Run in your project root. No special permissions required.
npm list solid-js
Look for solid-js@1.x. If the package is missing or a pre-release version, verify the memo behavior against the documentation for your installed version before relying on it.
When to use it
Use createMemo when a derived value is read in multiple places, costs more than a simple property access, or must stay stable while unrelated state changes. For side effects such as subscriptions or direct DOM manipulation, use createEffect instead.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.