Tim Givois
June 09, 2025 • 7 min.
Preact offers an optional library called Signals for fine-grained reactivity. Signals let you update only the components that depend on a value rather than re-rendering entire component trees. The official guide has a great introduction on the concept at preactjs.com.
yarn add preact @preact/signals
import { signal } from '@preact/signals'
const count = signal(0)
Read the current value with count.value
and update it by assigning to count.value
. Components that read this signal automatically re-render when the value changes.
import { useSignal, useComputed, useSignalEffect } from '@preact/signals'
export default function Counter() {
const count = useSignal(0)
const doubled = useComputed(() => count.value * 2)
useSignalEffect(() => {
console.log('Count changed', count.value)
})
return (
<div>
<button onClick={() => count.value++}>Increase</button>
<p>{count}</p>
<p>Double: {doubled}</p>
</div>
)
}
Signals tie your state updates directly to DOM updates. Even large component trees stay snappy because only the parts that use a signal will update. It's a small library and integrates nicely with Preact's tiny footprint. The blog post useSignal() is the Future of Web Frameworks dives deeper into why developers enjoy this model.
useSignal(initialValue)
creates a memoized signal inside a component.useComputed(fn)
derives values from other signals.useSignalEffect(fn)
runs side effects whenever a signal changes.Give Signals a try on your next Preact project and see how they feel!