Quick Start
Go from zero to reactive state in under 5 minutes.
This guide walks you through the core Stunk workflow — creating state, reading it, updating it, and reacting to changes.
Make sure you've completed Installation before continuing.
Create a chunk
A chunk is the fundamental unit of state in Stunk. You create one by calling chunk() with an initial value.
import { chunk } from "stunk";
const count = chunk(0);
const username = chunk("Fola");
const user = chunk({ name: "Fola", age: 25 });Chunks are defined outside components or functions — they are global reactive containers, not component-local state.
Read and update state
Every chunk has get(), peek(), set(), and reset() methods.
count.get(); // 0 — read and track as dependency
count.peek(); // 0 — read without tracking
count.set(10); // set directly
count.set((prev) => prev + 1); // update from previous value → 11
count.reset(); // back to initial value → 0Use peek() when you need the current value but don't want it to trigger recomputes in computed() or derived state.
Subscribe to changes
Use subscribe() to react to state changes outside of a framework:
const unsubscribe = count.subscribe((value) => {
console.log("count changed:", value);
});
count.set(5); // logs: "count changed: 5"
count.set(6); // logs: "count changed: 6"
// Clean up when done
unsubscribe();Use in React
Import useChunk from stunk/react to bind a chunk to a React component:
import { chunk } from "stunk";
import { useChunk } from "stunk/react";
const counter = chunk(0);
function Counter() {
const [count, setCount] = useChunk(counter);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount((n) => n + 1)}>Increment</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}The component re-renders only when counter changes — nothing else triggers a re-render.
Derive state
Derive a new reactive value from an existing chunk using .derive():
const price = chunk(100);
const discounted = price.derive((p) => p * 0.9);
price.set(200);
discounted.get(); // 180For deriving from multiple chunks, use computed(). In v3, dependencies are
tracked automatically — just call .get() on any chunk inside the function:
import { chunk, computed } from "stunk";
const price = chunk(100);
const quantity = chunk(3);
const total = computed(() => price.get() * quantity.get());
total.get(); // 300
quantity.set(5);
total.get(); // 500 — automatically recomputedNo dependency arrays. computed() tracks any chunk whose .get() is called
during execution. Use .peek() to read a value without registering it as a
dependency.
Putting it all together
Here's a complete example combining chunks, computed state, and React hooks:
import { chunk, computed } from "stunk";
import { useChunk, useChunkValue } from "stunk/react";
const price = chunk(50);
const quantity = chunk(2);
const total = computed(() => price.get() * quantity.get());
function Cart() {
const [qty, setQty] = useChunk(quantity);
const totalValue = useChunkValue(total);
return (
<div>
<p>Price: ${price.get()}</p>
<p>Quantity: {qty}</p>
<p>Total: ${totalValue}</p>
<button onClick={() => setQty((n) => n + 1)}>Add item</button>
<button onClick={() => setQty((n) => Math.max(0, n - 1))}>
Remove item
</button>
</div>
);
}