Skip to content

Solid.js Memos — Derived and Cached Values

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Solid.js Memos. We cover key concepts, practical examples, and best practices to help you master this topic.

Learn Solid.js memos: create cached computed values with createMemo, derive state from signals, and optimize performance with lazy evaluation.

In this lesson, you'll use createMemo() to create derived values that cache their results and only re-compute when dependencies change.

What You'll Learn

How to create memos, understand Caching and lazy evaluation, use memos in templates, and optimize expensive computations.

Why It Matters

Memos cache computed values and only re-calculate when dependencies change. This prevents unnecessary recalculations and improves performance for expensive operations.

Real-World Use

Doda Browser uses memos for search filtering: the filtered results list is a memo of the search query and the full item list.

flowchart LR
    A[Signal A] --> C[Memo]
    B[Signal B] --> C
    C --> D[Cached Result]
    C -->|Dependency Changes| E[Re-compute]
    style C fill:#2c4f7c,color:#fff

Basic Memo

import { createSignal, createMemo } from "solid-js";

const [items, setItems] = createSignal([1, 2, 3, 4, 5]);
const total = createMemo(() => items().reduce((a, b) => a + b, 0));

console.log(total()); // 15
// total() is cached until items() changes

Memo with Multiple Dependencies

const [price, setPrice] = createSignal(100);
const [quantity, setQuantity] = createSignal(2);
const [taxRate, setTaxRate] = createSignal(0.08);

const totalPrice = createMemo(() => {
  const subtotal = price() * quantity();
  return subtotal + subtotal * taxRate();
});

totalPrice() only re-computes when price, quantity, or taxRate changes.

Memo for Derived Display Values

function TodoList() {
  const [todos, setTodos] = createSignal([]);
  const [filter, setFilter] = createSignal("all");

  const filteredTodos = createMemo(() => {
    switch (filter()) {
      case "active": return todos().filter(t => !t.completed);
      case "completed": return todos().filter(t => t.completed);
      default: return todos();
    }
  });

  const stats = createMemo(() => ({
    total: todos().length,
    active: todos().filter(t => !t.completed).length,
    completed: todos().filter(t => t.completed).length,
  }));

  return (
    <div>
      <p>{stats().active} remaining</p>
      <For each={filteredTodos()}>{todo => <TodoItem todo={todo} />}</For>
    </div>
  );
}

Expensive Computation

const expensiveResult = createMemo(() => {
  console.log("Computing...");
  // Simulate expensive operation
  const data = doHeavyComputation(items());
  return data;
});

// First access: "Computing..." logged
// Second access: no log (cached)
// After items change: "Computing..." logged again

Common Mistakes

  1. Using effects instead of memos for derived values: Effects don't return values for use in templates. Use memos for computed display values.
  2. Not caching expensive computations: Filtering or sorting arrays in templates runs on every render. Use a memo.
  3. Mutating memo return values: Memos return cached objects. Mutating them persists across re-computations. Return new objects.
  4. Creating memos that don't read signals: A memo that reads no signals computes once and never updates.
  5. Over-memoizing: Simple arithmetic doesn't need memoization. Use memos for expensive operations.

Practice Questions

  1. How does createMemo differ from createSignal? Answer: Signals hold state with getter/setter. Memos derive values from signals and cache the result.

  2. When does a memo re-compute? Answer: Only when one of its signal dependencies changes. Otherwise, it returns the cached value.

  3. Is a memo lazy or eager? Answer: Lazy. The computation doesn't run until the first time the memo is read.

  4. Can a memo depend on another memo? Answer: Yes. Memos can depend on other memos, forming a dependency graph.

Challenge

Build a shopping cart with memos for subtotal, tax (8%), shipping (free over $50, otherwise $5), and total. Each memo depends on the previous one.

Mini Project

Create a real-time search filter: a list of 100 names, a signal for the search query, a memo that filters the list, and a display component showing the filtered count and names.

FAQ

Can I use a memo for asynchronous operations?

: No. Memos must be synchronous. Use createResource for async data fetching.

What happens if a memo throws?

: The error propagates to the component. Wrap memo computations in try/catch for error handling.

Are memos garbage collected?

: Yes. When the owning component unmounts and all references are gone, the memo is collected.

Can I create a writable memo?

: No. Memos are read-only derived values. Use signals for writable state.

What's Next

Learn about Solid.js Batching for grouping signal updates and optimizing performance.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro