github solidjs/solid v2.0.0-beta.0
v2.0.0 Beta - The <Suspense> is Over

pre-release5 hours ago

I know you all probably weren't expecting this announcement next. But after reviewing the roadmap, we spent so long iterating in the Experimental phase, most of the goalposts within Alpha don't appear relevant enough to warrant their own phase. Instead, I'm happy to announce today that Solid 2.0 effort enters the beta stage. There will be bugs and rough edges we need to work through with the ecosystem. The focus will be on building documentation, and strategies for migration while we work through extending 2.0 into the wider ecosystem.

The Big Ideas

  • Async is first‑class: computations can return Promises (or async iterables) and the graph knows how to suspend/resume work.
  • <Loading> is for initial readiness: show a fallback while a subtree can’t produce UI yet — then keep the UI stable while background work happens.
  • Pending UI is an expression, not a flag: isPending(() => expr) tells you when “refreshing…” work is in flight without tearing down the UI.
  • Mutations have a home: action(...) + optimistic primitives (createOptimistic, createOptimisticStore) let you write “optimistic → await → refresh” as one coherent flow.
  • Derived state is a primitive: function forms like createSignal(fn) and createStore(fn) make derived-but-writable patterns explicit and composable.
  • A more predictable scheduler: updates are microtask‑batched, and reads don’t update until the batch flushes (use flush() only when you truly need “settle now”).
  • Dev guardrails: dev warnings catch accidental “top-level reads” in components and writes in reactive scopes before they become async bugs.
  • DOM model cleanup: use: directives are replaced by ref directive factories (with array composition), and classList is folded into class.

Tiny Examples

Stable async UI: <Loading> for first render, isPending for revalidation

const users = createMemo(() => api.listUsers());
const refreshing = () => isPending(() => users());

<>
  <Show when={refreshing()}>{/* subtle "refreshing…" UI */}</Show>
  <Loading fallback={<Spinner />}>
    <UserList users={users()} />
  </Loading>
</>

Mutations that read clearly: action + optimistic store + refresh

const [todos, setOptimisticTodos] = createOptimisticStore(() => api.getTodos(), []);

const addTodo = action(function* (todo) {
  setOptimisticTodos(todos => {
    todos.push(todo)
  }); // optimistic UI
  yield api.addTodo(todo);                   // server write
  refresh(todos);                            // recompute derived reads
});

Batching that’s deterministic: reads update after flush()

const [count, setCount] = createSignal(0);
setCount(1);
count(); // still 0
flush();
count(); // now 1

Breaking changes you’ll notice quickly

  • List rendering: Index is replaced by <For keyed={false}>, and For children receive accessors (item() / i()).
  • Effects & lifecycle: createEffect is split (compute → apply), and onMount is replaced by onSettled (which can return cleanup).
  • Stores: setters are draft-first by default; storePath(...) exists as an opt-in helper if you want the old path-style ergonomics.
  • DOM: use: directives are removed; use ref directive factories (and arrays) instead.

Try the beta

Start with the migration guide:

Then dive into specific topics when you need details:

Conclusion

Today we have an overview of what has changed and 7 RFCs to describe each area in more detail. Noticeably absent are features marked as experimental in 1.0 like enableExternalSource and SuspenseList. These will be fleshed out during the beta phase but does not block us on core mechanics. Similarly the 2.0 is missing dev hooks to enable dev tools at this point because the signals implementation has been rewritten from the ground up.

We have also updated Vite Plugin Solid which will find on npm under the next tag. Over the next several days I expect to see more 1st party updates following a similar patterns. This has been a long time coming but I couldn't be more excited to finally put in your hands what we've been working on for the last couple years.

Big thanks to @milomg, @mihar-22, @devagrawal09, @titoBouzout, @tannerlinsley, @lxsmnsyc, @GabbeV, @brenelz, and everyone else that has contributed code, time, ideas, and testing for this release.

Best Regards,
@ryansolid

Don't miss a new solid release

NewReleases is sending notifications on new releases.