Async as a First-Class Feature in SolidJS 2.0
SolidJS 2.0 Beta marks a significant shift toward being an async-first JavaScript framework. Instead of treating Promises as a special case, the framework now lets computations directly return Promises while the reactive graph manages suspension and resumption behind the scenes. Developers can, for example, pass a Promise straight into createMemo and rely on SolidJS to orchestrate when the computed value becomes available. This removes much of the manual wiring that previously surrounded asynchronous data flows in reactive component libraries. The new model is designed to make async logic feel native rather than bolted on, aligning with how modern applications depend on network calls and server mutations. Early community feedback highlights “relief and joy” at async being elevated to a core capability, with many praising how “slick” the new patterns appear in practice.
Reworked Suspense and Pending State Handling
Suspense in SolidJS has been reimagined to better align with real-world loading patterns. Previously, Suspense could feel jarring when it tore down the UI to show a fallback each time async work re-ran. In SolidJS 2.0, the new Loading behavior focuses on initial readiness only: a fallback is shown while a subtree loads for the first time, but once ready, the UI remains stable. Pending state is now modeled via isPending(() => expr), allowing developers to express ongoing async work without constantly unmounting and remounting components. This gives users a smoother visual experience while keeping developers in control of loading indicators and skeleton states. Community members migrating projects like TanStack Start and SolidStart describe the new async and Suspense model as feeling more thoughtful, reducing surprises when data refreshes and making complex async flows easier to reason about.
Deterministic Batching and New Reactive Primitives
SolidJS 2.0 introduces deterministic batching to make reactivity more predictable and performant. Updates are now microtask-batched, with reactive reads reflecting changes only after an explicit flush() boundary. This scheduling model aims to provide consistent behavior in async-heavy scenarios, even if it alters the mental model for developers who relied on immediate signal updates in SolidJS 1.x. Derived state also becomes a first-class primitive through function-based forms such as createSignal(fn) and createStore(fn), making it easier to express state that depends on other signals or stores. On the mutation side, action() combined with createOptimisticStore offers a cohesive way to describe optimistic updates, server writes, and subsequent revalidation in a single flow. While some developers have expressed concern that split-phase createEffect and flush-based updates feel more cumbersome, the framework’s author argues these trade-offs are necessary to achieve consistent async semantics.
Developer Experience, Breaking Changes, and Adoption Outlook
The SolidJS 2.0 release brings a series of breaking changes aimed at simplifying everyday usage while embracing async by default. Index is replaced by
