Skip to content

What is the Difference Between SolidJS 2.0 Loading and Suspense?

I was reading through the SolidJS 2.0 beta announcement when I saw something that caught me off guard: a new Loading component alongside the existing Suspense. Why add another component for async data handling?

The naming felt redundant at first. “Loading” and “Suspense” both handle async states, right? But after digging into the behavior differences, I realized this wasn’t about adding complexity—it was about fixing a user experience problem that React’s Suspense pattern created.

The Problem with Traditional Suspense

React’s Suspense pattern shows a loading fallback every time async data is being fetched. This sounds reasonable until you think about real user interactions:

  • A user is viewing a list and clicks “next page”
  • A user applies a filter to existing data
  • A user refreshes data they’re already viewing

In these scenarios, showing a full loading screen is jarring. The user just wants to see the updated content with an indication that new data is loading.

Traditional Suspense Flow:
┌─────────────────────────────────────────────────────────────┐
│ User Action → Loading Fallback → Content → User Action → │
│ Loading Fallback → ... │
└─────────────────────────────────────────────────────────────┘
What Users Actually Expect:
┌─────────────────────────────────────────────────────────────┐
│ User Action → Loading Fallback → Content → User Action → │
│ Stale Content + Pending Flag → │
│ Updated Content │
└─────────────────────────────────────────────────────────────┘

This pattern—showing stale UI with a pending indicator—is so common that React developers often build custom solutions on top of Suspense.

SolidJS 2.0’s Solution: Loading Component

SolidJS 2.0 introduces the Loading component with built-in “optimistic UI” behavior:

First Load:
Component mounts → Async fetch starts → Show Loading fallback →
Data arrives → Show content
Subsequent Updates:
User triggers update → Async fetch starts → Show previous content
(with pending flag) → Data arrives → Update content

The key difference: Loading only happens once, when loading the first async data. After that, async changes show the previous UI with a pending flag so it can be styled to show that loading new data is in progress.

Basic Loading Usage

UserProfile.jsx
import { Loading } from 'solid-js';
function UserProfile({ userId }) {
return (
<Loading fallback={<ProfileSkeleton />}>
<ProfileContent userId={userId} />
</Loading>
);
}
// First load: Shows ProfileSkeleton
// Subsequent userId changes: Shows previous ProfileContent with pending flag

The pending flag allows you to style the stale UI to indicate loading is in progress. You could apply an opacity change, show a subtle loading spinner overlay, or display a progress bar.

Using the Pending Flag

ProfileContent.jsx
function ProfileContent({ userId }) {
const [user] = createUserResource(userId);
const isPending = usePending(); // Hypothetical API - verify with docs
return (
<div class={isPending() ? 'opacity-50' : ''}>
<h1>{user().name}</h1>
{isPending() && <LoadingSpinner />}
</div>
);
}

This gives you fine-grained control over how to indicate loading state without disrupting the user’s view of the existing content.

When to Use Each

ScenarioComponentBehavior
First-time page loadLoadingShows fallback
First-time page loadSuspenseShows fallback
Pagination/filteringLoadingShows stale UI + pending
Pagination/filteringSuspenseShows fallback
Background refreshLoadingShows stale UI + pending
Background refreshSuspenseShows fallback

Use Loading when you want smooth transitions during data updates. Use Suspense when you need a full loading state on every fetch.

Why the Rename?

From the Reddit discussion: “it works differently, hence the rename.”

The SolidJS team deliberately chose a new name to distinguish the behavior from React’s Suspense pattern. This isn’t just marketing—it’s a fundamental difference in how async state is handled.

React developers who want the “show stale UI with pending indicator” pattern typically need to build it themselves on top of Suspense. SolidJS 2.0 bakes this behavior into the Loading component by default.

Common Mistakes

  1. Using Loading for everything: If you need a full loading state on every fetch, use Suspense instead.

  2. Ignoring the pending flag: The pending state is key to the Loading pattern—use it to provide visual feedback.

  3. Mixing patterns inconsistently: Choose one approach per component tree for predictable behavior.

  4. Assuming it works like React Suspense: The behaviors differ significantly on subsequent fetches.

Traditional Suspense (Still Available)

If you prefer the traditional behavior, Suspense is still available:

TraditionalSuspense.jsx
import { Suspense } from 'solid-js';
function UserProfile({ userId }) {
return (
<Suspense fallback={<ProfileSkeleton />}>
<ProfileContent userId={userId} />
</Suspense>
);
}
// Every fetch (initial + updates) shows ProfileSkeleton

Final Thoughts

SolidJS 2.0’s Loading component provides a better default for async data handling by showing stale UI with a pending indicator on subsequent fetches. This matches real user expectations better than showing a loading spinner on every data update.

The key insight here is that users don’t want their context destroyed on every data refresh—they want to see what they were looking at while new data loads. React developers have been building custom solutions for this pattern for years. SolidJS 2.0 makes it the default.

Important: The code examples above are conceptual based on the plan. Verify the exact API with official SolidJS 2.0 documentation before implementation.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments