Select
Create a read-only derived chunk from a single source with optional shallow equality.
select() creates a read-only derived chunk from a source chunk using a selector function. It's similar to .derive() but adds one important option — shallow equality checking — which prevents unnecessary updates when your selector returns an object.
import { chunk, select } from "stunk";
const user = chunk({ name: "Fola", age: 25, role: "admin" });
const userName = select(user, (u) => u.name);
userName.get(); // "Fola"
user.set((prev) => ({ ...prev, age: 26 })); // age changed, name didn't
userName.get(); // "Fola" — no update triggeredShallow equality
By default, select() uses strict reference equality (!==) to detect changes. This is fine for primitives, but for object selectors a new object reference always triggers an update even if the contents are identical.
Enable useShallowEqual to compare object contents instead:
const user = chunk({ name: "Fola", age: 25 });
// Without useShallowEqual — new reference = always updates
const info = select(user, (u) => ({ name: u.name, age: u.age }));
// With useShallowEqual — only updates when name or age actually changes
const info = select(user, (u) => ({ name: u.name, age: u.age }), {
useShallowEqual: true,
});This is especially useful in React — it prevents re-renders when selecting a slice of a large object chunk that hasn't meaningfully changed.
Read-only
select() returns a ReadOnlyChunk<T> — set() and reset() are not present on the returned object. Update the source chunk instead:
const userName = select(user, (u) => u.name);
// @ts-expect-error — set does not exist on ReadOnlyChunk
userName.set("Tunde");
// Update source instead
user.set((prev) => ({ ...prev, name: "Tunde" }));
userName.get(); // "Tunde"Chaining
Selectors can be chained — each returns a new ReadOnlyChunk that inherits the same options:
const user = chunk({ profile: { name: "Fola", age: 25 } });
const profile = select(user, (u) => u.profile);
const name = select(profile, (p) => p.name);In React
Define outside the component, then read with useChunkValue():
import { chunk, select } from "stunk";
import { useChunkValue } from "stunk/react";
const user = chunk({ name: "Fola", age: 25, role: "admin" });
const userName = select(user, (u) => u.name, { useShallowEqual: true });
function UserName() {
const name = useChunkValue(userName);
return <p>Hello, {name}</p>;
}select() vs .derive()
.derive() | select() | |
|---|---|---|
| Syntax | Method on chunk | Standalone import from stunk |
| Read-only | Yes | Yes |
| Shallow equality | No | Yes (useShallowEqual) |
| Chainable | Yes | Yes |
| Best for | Simple transforms | Object slices, perf-sensitive selectors |