Creates a reactive value and returns a getter/setter pair.
import { createSignal } from '@barefootjs/client'
const [getter, setter] = createSignal<T>(initialValue: T)const [count, setCount] = createSignal(0)
count() // 0 — read by calling the getter
setCount(5) // write a value
setCount(n => n + 1) // write with an updater function; count() is now 6The getter is a function call — count(), not count. That call is what registers a dependency. The type is inferred from the initial value; pass a type parameter for unions: createSignal<User | null>(null).
Called with no argument, the signal starts as undefined, and its type includes undefined: createSignal<User>() returns a User | undefined getter.
#Equality check
The setter compares with Object.is. Setting the same value does nothing, so an object or array needs a new reference to trigger an update:
const [todos, setTodos] = createSignal([{ text: 'Buy milk' }])
// ❌ Mutating the same array — no update
const list = todos()
list.push({ text: 'Walk dog' })
setTodos(list) // Same reference, Object.is returns true
// ✅ New array — triggers update
setTodos([...todos(), { text: 'Walk dog' }])#See also
createMemo— values derived from signalsbatch— group several writes into one update