Basic reactivity

createResource

Edit this page

Creates a reactive resource that manages asynchronous data fetching and loading states, automatically tracking dependencies and providing a simple interface for reading, refreshing, and error handling. It integrates with Solid's reactivity system and Suspense boundaries.


Import

import { createResource } from "solid-js";

Type

// Without source
function createResource<T, R = unknown>(
fetcher: ResourceFetcher<true, T, R>,
options?: ResourceOptions<T>
): ResourceReturn<T, R>;
// With source
function createResource<T, S, R = unknown>(
source: ResourceSource<S>,
fetcher: ResourceFetcher<S, T, R>,
options?: ResourceOptions<T, S>
): ResourceReturn<T, R>;
type ResourceReturn<T, R = unknown> = [Resource<T>, ResourceActions<T, R>];
type Resource<T> = {
(): T | undefined;
state: "unresolved" | "pending" | "ready" | "refreshing" | "errored";
loading: boolean;
error: any;
latest: T | undefined;
};
type ResourceActions<T, R = unknown> = {
mutate: (value: T | undefined) => T | undefined;
refetch: (info?: R) => Promise<T> | T | undefined;
};
type ResourceSource<S> =
| S
| false
| null
| undefined
| (() => S | false | null | undefined);
type ResourceFetcher<S, T, R = unknown> = (
source: S,
info: { value: T | undefined; refetching: R | boolean }
) => T | Promise<T>;
interface ResourceOptions<T, S = unknown> {
initialValue?: T;
name?: string;
deferStream?: boolean;
ssrLoadFrom?: "initial" | "server";
storage?: (
init: T | undefined
) => [Accessor<T | undefined>, Setter<T | undefined>];
onHydrated?: (k: S | undefined, info: { value: T | undefined }) => void;
}

Parameters

source

  • Type: ResourceSource<S>
  • Default: undefined

Reactive data source evaluated before the fetcher runs. When the value is undefined, null, or false, the fetcher is not called. Otherwise the current value is passed as the first fetcher argument. Each change triggers the fetcher again.

fetcher

  • Type: ResourceFetcher<S, T, R>

Function that receives the source value (or true if no source), the current resource info, and returns a value or Promise.

options

  • Type: ResourceOptions<T, S>
  • Default: {}

Configuration options for the resource.

initialValue

  • Type: T
  • Default: undefined

Initial value for the resource. When provided, the resource starts in "ready" state and the type excludes undefined.

name

  • Type: string
  • Default: undefined

A name for debugging purposes in development mode.

deferStream

  • Type: boolean
  • Default: false

Controls streaming behavior during server-side rendering.

ssrLoadFrom

  • Type: "initial" | "server"
  • Default: "server"

Determines how the resource loads during SSR hydration.

  • "server": Uses the server-fetched value during hydration.
  • "initial": Re-fetches on the client after hydration.

storage

  • Type: (init: T | undefined) => [Accessor<T | undefined>, Setter<T | undefined>]
  • Default: createSignal

Custom storage function for the resource value, useful for persistence or custom state management.

onHydrated

  • Type: (k: S | undefined, info: { value: T | undefined }) => void
  • Default: undefined

Callback fired when the resource hydrates on the client side.


Return value

  • Type: [Resource<T>, ResourceActions<T, R>]

Returns a tuple containing the resource accessor and resource actions.

Resource

type Resource<T> = {
(): T | undefined;
state: "unresolved" | "pending" | "ready" | "refreshing" | "errored";
loading: boolean;
error: any;
latest: T | undefined;
};
  • state: Current state of the resource. See the table below for state descriptions.
  • loading: Indicates if the resource is currently loading.
  • error: Error information if the resource failed to load.
  • latest: The latest value of the resource.
StateDescriptionLoadingErrorLatest
unresolvedInitial state, not yet fetchedfalseundefinedundefined
pendingFetching in progresstrueundefinedundefined
readySuccessfully fetchedfalseundefinedT
refreshingRefetching while keeping previous valuetrueundefinedT
erroredFetching failedfalseanyundefined

ResourceActions

type ResourceActions<T, R = unknown> = {
mutate: (value: T | undefined) => T | undefined;
refetch: (info?: R) => Promise<T> | T | undefined;
};
  • mutate: Function to manually overwrite the resource value without calling the fetcher. Allows you to optimistically update the resource value locally, without making a network request.
  • refetch: Function to re-run the fetcher without changing the source. If a parameter is provided to refetch, it will be passed to the fetcher's refetching property.

Examples

Basic usage

const [data] = createResource(async () => {
const response = await fetch("/api/data");
return response.json();
});
// Access data
console.log(data()); // undefined initially, then fetched data
console.log(data.loading); // true during fetch
console.log(data.state); // "pending" → "ready"

With source

const [userId, setUserId] = createSignal(1);
const [user] = createResource(userId, async (id) => {
const response = await fetch(`/api/users/${id}`);
return response.json();
});
// Automatically refetches when userId changes
setUserId(2);

With actions

const [posts, { refetch, mutate }] = createResource(fetchPosts);
// Manual refetch
await refetch();
// Optimistic update
mutate((posts) => [...posts, newPost]);

Error handling

const [data] = createResource(async () => {
const response = await fetch('/api/data');
if (!response.ok) throw new Error('Failed to fetch');
return response.json();
});
// In JSX
<ErrorBoundary fallback={<div>Error loading data</div>}>
<div>{data()?.title}</div>
</ErrorBoundary>

With initial value

const [user] = createResource(() => fetchUser(), {
initialValue: { name: "Loading...", id: 0 },
});
// user() is never undefined
console.log(user().name); // "Loading..." initially
Report an issue with this page