StunkStunk
Core Concepts

Derive

Create reactive derived state from a single chunk using .derive().

.derive() is a method on every chunk that creates a new reactive 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 — you can't set it directly. 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. If you destroy the source chunk, the derived chunk stops receiving updates automatically.

If you want 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);

// Stop listening to price, but price still works fine
discounted.destroy();

In React, cleanup happens automatically when the component unmounts. Manual destroy() is only needed when using derived chunks outside of React.


In React

Derive your data outside the component, then pass it to useChunkValue() since you're only reading:

import { chunk } from "stunk";
import { useChunkValue } from "stunk/react";

const price = chunk(100);
const discounted = price.derive((p) => p * 0.9); // derived outside

function DiscountedPrice() {
  const value = useChunkValue(discounted); // read-only

  return <p>Discounted: ${value}</p>;
}

useDerive exists in v2 but will be removed in v3. It adds no value over deriving outside the component and passing to useChunkValue(). Start using the pattern above now.


What's next?

On this page