Skip to main content
Solid.js v2

createAsync

createAsync provides a way to fetch data asynchronously and reactively.

Basic Usage

import { createAsync } from "solid-js";
function UserProfile(props: { userId: string }) {
const user = createAsync(() => fetchUser(props.userId));
return <div>Name: {user().name}</div>;
}

createAsync will automatically rerun when props.userId changes.

Loading States

Async signals in Solid v2 don't return undefined when loading. They always return the resolved value.

To handle initial loading states, wrap the signal read with <Suspense />.

import { Suspense } from "solid-js";
function UserProfile(props: { userId: string }) {
const user = createAsync(() => fetchUser(props.userId));
return (
<Suspense fallback={<div>Loading user...</div>}>
<div>Name: {user().name}</div>
</Suspense>
);
}

The Suspense fallback is only shown when UserProfile is rendered and fetchUser is pending. It does not trigger when props.userId changes and fetchUser reruns.

To handle updates to existing async signals, use isPending.

import { Suspense, isPending } from "solid-js";
function UserProfile(props: { userId: string }) {
const user = createAsync(() => fetchUser(props.userId));
return (
<Suspense fallback={<div>Loading user...</div>}>
<div class={isPending(user) ? "loading" : ""}>Name: {user().name}</div>
</Suspense>
);
}

isPending only returns true when an existing async signal reruns. It does not trigger when a new async signal is created.

Error Handling

To handle error states, wrap the signal read with <ErrorBoundary />.

import { ErrorBoundary } from "solid-js";
function UserProfile(props: { userId: string }) {
const user = createAsync(() => fetchUser(props.userId));
return (
<ErrorBoundary fallback={<div>Error loading user</div>}>
<Suspense fallback={<div>Loading user...</div>}>
<div>Name: {user().name}</div>
</Suspense>
</ErrorBoundary>
);
}

Reactive tracking inside createAsync

You can only subscribe to dependencies in sync part of your function, i.e. before awaiting promises.

In the following example we fetch random user and trying to refetch the data on button click.

import { createAsync, createSignal, Suspense, isPending } from "solid-js";
const fetchRandomUser = () =>
new Promise<{ name: string }>((resolve) => {
setTimeout(() => resolve({ name: `User ${Math.random()}` }), 1000);
});
function IncorrectSubscriptionExample() {
const [refetchSignal, refetch] = createSignal(undefined, { equals: false });
const randomUserName = createAsync(async () => {
// This is synchronous part of the function (before `await`)
const user = await fetchRandomUser();
// after `await` we cannot subscribe to signals anymore
// refetch WILL NOT WORK
refetchSignal();
return user.name;
});
return (
<section>
<Suspense fallback={<p>Loading user...</p>}>
<p>User name: {randomUserName()}</p>
<button disabled={isPending(randomUserName)} onClick={() => refetch()}>
Refetch user (not working)
</button>
</Suspense>
</section>
);
}
function CorrectSubscriptionExample() {
const [refetchSignal, refetch] = createSignal(undefined, { equals: false });
const randomUserName = createAsync(async () => {
// This is synchronous part of the function (before `await`)
// Here we can subscribe to reactive values
// refetch WILL WORK
refetchSignal();
return (await fetchRandomUser()).name;
});
return (
<section>
<Suspense fallback={<p>Loading user...</p>}>
<p>User name: {randomUserName()}</p>
<button disabled={isPending(randomUserName)} onClick={() => refetch()}>
Refetch user (working)
</button>
</Suspense>
</section>
);
}

Last updated: 4/26/25, 4:52 AM

Edit this page on GitHub
Solid.js v2Rough WIP docs for Solid 2.0.