Derive
Create reactive derived state from a single chunk using .derive().
.derive() is a method on every chunk that creates a new reactive, read-only chunk based on a transformation function. The derived chunk updates automatically whenever the source changes.
import { chunk } from "stunk";
const price = chunk(100);
const discounted = price.derive((p) => p * 0.9);
const formatted = price.derive((p) => `₦${p.toFixed(2)}`);
price.set(200);
discounted.get(); // 180
formatted.get(); // "₦200.00"The derived chunk is read-only at the TypeScript type level — set() and reset() do not exist on ReadOnlyChunk<T>. Update the source chunk instead.
Chaining
Derived chunks can themselves be derived:
const count = chunk(10);
const doubled = count.derive((n) => n * 2);
const label = doubled.derive((n) => `Value: ${n}`);
count.set(5);
label.get(); // "Value: 10"Cleanup
A derived chunk stays subscribed to its source as long as both exist. To stop a derived chunk from updating while keeping the source alive, call destroy() on the derived chunk:
const discounted = price.derive((p) => p * 0.9);
discounted.destroy(); // stops listening, source still worksIn React, cleanup happens automatically when the component unmounts. Manual
destroy() is only needed when using derived chunks outside of React.
In React
Define the derived chunk outside the component, then read with useChunkValue():
import { chunk } from "stunk";
import { useChunkValue } from "stunk/react";
const price = chunk(100);
const discounted = price.derive((p) => p * 0.9);
function DiscountedPrice() {
const value = useChunkValue(discounted);
return <p>Discounted: ${value}</p>;
}.derive() vs select() vs computed()
.derive() | select() | computed() | |
|---|---|---|---|
| Source | Single chunk | Single chunk | Multiple chunks |
| Shallow equality | No | Yes (useShallowEqual) | Yes (automatic) |
| Chainable | Yes | Yes | Via derive() |
| Best for | Simple transforms | Object slices | Multi-chunk derivation |