Plain createSignal<T[]> works, but it is clumsy for in-place array mutation. createArraySignal exists to make that case honest and cheap.
import { createArraySignal } from "@kayahr/signal";
const [ items, array ] = createArraySignal([ 1, 2, 3 ]);
items() returns a readonly snapshot. array exposes the mutation API.
The mutator supports:
pushpopunshiftshiftsplicesetupdatereplaceclearExample:
array.push(4);
array.set(0, 10);
array.update(1, value => value * 2);
console.log(items()); // [10, 4, 3, 4]
items() intentionally returns a readonly snapshot, not the mutable backing array.
That matters for two reasons:
createMemo(() => items()) still get a fresh array identity after mutations, so equality checks stay honest.The implementation does not clone on every write and every read. Writes mark the snapshot dirty, and the next read rebuilds it once.
Array signals do not do deep array comparisons. Mutations know exactly when a structural change happened and invalidate dependents directly.
That is the whole point. Deep equality here would add cost without solving the real problem.
set(index, value) and update(index, fn) validate the index and throw RangeError for invalid positions.
Use array signals for:
push, splice, set or similar mutation-style operationsUse a plain signal of type T[] when replacing the whole array value is already the natural update model.