Skip to main content
Solid.js v2

createSignal

createSignal is the fundamental reactive primitive in Solid. It creates a signal with a getter and setter.

Definition

type Signal<T> = [get: Accessor<T>, set: Setter<T>];
function createSignal<T>(): Signal<T | undefined>;
// `createSignal` can also accept initial value as a parameter
function createSignal<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
// or it can accept another signal (see `Derived Signals` example)
function createSignal<T>(
fn: ComputeFunction<T>,
initialValue?: T,
options?: SignalOptions<T>
): Signal<T>;
interface SignalOptions<T> {
name?: string;
equals?: ((prev: T, next: T) => boolean) | false;
}

Basic Usage

import { createSignal } from "solid-js";
function Counter() {
const [count, setCount] = createSignal(0);
return <button onClick={() => setCount((c) => c + 1)}>{count()}</button>;
}

Derived Signals

Signals can be derived from other signals. This is useful for creating derived state that can be updated locally, and also resets when dependencies update.

import { createSignal } from "solid-js";
function Child(props: { count: number }) {
const [childCount, setChildCount] = createSignal(() => props.count);
return <button onClick={() => setChildCount((c) => c + 1)}>{childCount()}</button>;
}
function Parent() {
const [count, setCount] = createSignal(0);
return (
<div>
<Child count={count()} />
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}

Here updating count will also update childCount, but updating childCount will not affect count.

equals parameter

You can pass equals parameter to customize signal update behavior. By default values compared with ===, however you can set your own behavior:

function CustomEqualsExample() {
const [value, setValue] = createSignal(0, {
// Do not update signal when we value is more than 5
equals: (_prev, next) => next > 5,
});
return (
<section>
<p>Value will not be more than (5): {value()}</p>
<button onClick={() => setValue((value) => value + 1)}>Increase value</button>
</section>
);
}

Special case equals: false

There are special cases when you might need to pass equals: false.

For instance, you might want to implement refetch functioanlity:

import { createSignal, createAsync, isPending, Suspense } from "solid-js";
const fetchRandomNumber = () =>
new Promise<number>((resolve) => {
setTimeout(() => resolve(Math.random()), 1000);
});
function RefetchExample() {
const [refetchSignal, refetch] = createSignal(undefined, { equals: false });
const randomNumber = createAsync(() => {
// subscribe to refetch signal
refetchSignal();
return fetchRandomNumber();
});
return (
<section>
<p>
Random number:{" "}
<Suspense fallback="Loading number...">
<Show when={!isPending(randomNumber)} fallback="Refetching number...">
{randomNumber()}
</Show>
</Suspense>
</p>
<button onClick={refetch} disabled={isPending(randomNumber)}>Refetch number</button>
</section>
);
}

Another usecase is when you want to reduce memory allocation. In Solid (in comparison to React) signals can be mutable. In the following example we don't need to create a new object every time to update the signal. Instead, we can just mutate the object. If you build high-load app, this trick can help you to optimize memory and GC calls.

function SignalMutationExample() {
// Calling `updateObject` will always trigger the signal
const [object, updateObject] = createSignal({ value: 0 }, { equals: false });
return (
<section>
<p>Object value: {object().value}</p>
<button
onClick={() =>
updateObject((object) => {
// Here we're not creating new object
// Instead we just mutate the value inside
object.value++;
return object;
})
}
>
Increase object value
</button>
</section>
);
}

You should be careful with equals: false, because it may lead to unnecessary signal triggers which can lead to unnecessary computations.

Last updated: 5/3/25, 3:34 AM

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