Async Values Are Now First-Class

Solid 2.0 elevates asynchronous values to first-class citizens. In 1.x, you used createResource to handle async data. Now, you can feed any Promise or async generator to createMemo inside a `` boundary, and it returns the same thing as a synchronous memo. The initial undefined state is swallowed by the boundary.

// Solid-1.x
const [data] = createResource(() => fetchUser(userId()));

// Solid-2.0
const data = createMemo(() => fetchUser(userId()));

Optimistic Signals and Stores

Optimistic updates were a rough edge in 1.x. You had to couple multiple resources loosely. 2.0 introduces createOptimistic and action for cleaner optimistic updates.

// Solid-1.x
const [message, setMessage] = createSignal(undefined);
const [messages, { mutate, refetch }] = createResource(
  () => chatServer.loadMessages(),
  { initialValue: [] }
);
const [send] = createResource(
  message,
  (next) => chatServer.sendMessage(next)
);
const sendMessage = (next) => {
  mutate([...messages(), next]);
  setMessage(next);
};
createEffect(on(send, refetch));

// Solid-2.0
const [messages, setMessages] =
  createOptimistic(() => chatServer.loadMessages());
const sendMessages = action(function*(next) {
  setMessages(m => [...m, next]);
  yield chatServer.sendMessage(next);
  refresh(messages);
});

With optimistic stores, you get fine-grained reactivity.

Asynchronous Updates Change Signal Behavior

Updates that were previously synchronous are now asynchronous. You must handle stale values.

// Solid-1.x
const [count, setCount] = createSignal(0);
setCount(1);
console.log(count()); // 1

// Solid-2.0
const [count, setCount] = createSignal(0);
setCount(1);
console.log(count()); // 0 (stale!)
console.log(latest(count)); // 1
flush();
console.log(count()); // 1

Use latest for synchronous resolution of a single signal, or flush for all batched actions.

Effects Split into Subscription and Computation

Effects now take two arguments: a dependency function and a computation function. This is similar to createEffect(on(...)).

// Solid-1.x
createEffect(() => apiCallA(signalB()));

// Solid-2.0
createEffect(signalB, apiCallA);

// Multiple dependencies use tuples
createEffect(
  () => [signalA(), signalB()],
  ([a, b]) => a && apiCall(b)
);

isPending allows fine-grained monitoring of unresolved state.

Renamed APIs and Breaking Changes

  • solid-js/web becomes @solidjs/web; exports isServer.
  • (holds rendering until first async load).
  • .
  • onMountonSettled (return function is now cleanup).
  • merged into.
  • Store setters now work like auto-reconcile; path setting via storePath helper.
  • unwrap(store)snapshot(store).
  • mergeProps/splitPropsmerge/omit.

Removed Features

  • /*@once*/ pragma and directives removed; use untrack and ref (now supports array of ref functions).
  • classList removed; class now supports objects and arrays.
// Solid-2.0

  {props.children}

Context Changes

createContext returns the provider component itself.

// Solid-1.x
const Theme = createContext("light");
...

// Solid-2.0
const Theme = createContext("light");
...

useContext throws if no provider is found, so the return type is T instead of T | undefined.

Store Improvements

Store setters now use mutable proxies. Path selection is still available via storePath.

// Solid-2.0
setState(x => { x.todos[id].done = true; });
// or
setState(storePath('todos', id, 'done', true));

reconcile now accepts a key function for faster position detection.

setState(reconcile(nextTodos, "id"));
// previous behavior:
setState(reconcile(nextTodos, () => true));

Derived stores: createProjection (read-only) and createStore(fn, seed) (writable).

Agentic Awesomeness

Solid 2.0 ships with specialized documentation to help LLMs generate correct Solid code, addressing issues where models trained on React produced incorrect Solid-1.x code.

Ecosystem Status

Current version is in beta. For @solidjs/testing-library, use "solidjs/solid-testing-library#next" in package.json. Community primitives pre-release is coming. Storybook-solid early versions work. TanStack Start already supports 2.0; SolidStart 2.0 integration is in progress.

Migration Steps

  1. Use createMemo instead of createResource for async data.
  2. Replace classList with class accepting objects/arrays.
  3. Update effects to two-argument form.
  4. Change onMount to onSettled.
  5. Switch to new context API.
  6. Use latest/flush for synchronous reads.
  7. Replace unwrap with snapshot.
  8. Test with beta.