StunkStunk
Getting Started

Installation

Get Stunk up and running in your project in under a minute.

Install

Stunk has zero dependencies. Install the core package with your package manager of choice:

npm install stunk
pnpm add stunk
yarn add stunk
bun add stunk

That's it. No config files, no providers, no boilerplate.


Package Exports

Stunk ships four importable paths:

ImportDescription
stunkCore — chunk, computed, select, batch, isChunk and more
stunk/reactReact hooks — useChunk, useChunkValue, useAsyncChunk, useInfiniteAsyncChunk
stunk/queryAsync layer — asyncChunk, infiniteAsyncChunk, combineAsyncChunks
stunk/middlewareMiddleware — history, persist, logger, nonNegativeValidator
import { chunk, computed } from "stunk";
import { useChunk, useAsyncChunk } from "stunk/react";
import { asyncChunk, infiniteAsyncChunk } from "stunk/query";
import { history, persist, logger } from "stunk/middleware";

Framework Setup

Vanilla JS / TypeScript

No setup required. Import and use directly:

import { chunk } from "stunk";

const count = chunk(0);

count.set(1);
console.log(count.get()); // 1

React

Stunk supports React 17, 18, and 19. React is a peer dependency — if it's already in your project, you're good.

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

const counter = chunk(0);

function Counter() {
  const [count, setCount] = useChunk(counter);

  return <button onClick={() => setCount((n) => n + 1)}>Count: {count}</button>;
}

Chunks are defined outside components. This is intentional — a chunk is global reactive state, not component-local state. Define it once, use it anywhere.

Vue (WIP)

Vue support is currently in progress via stunk/vue. Follow the GitHub repo for updates.


TypeScript

Stunk is written in TypeScript and ships its own types — no @types/stunk needed. Full type inference works out of the box:

import { chunk } from "stunk";

const count = chunk(0); // Chunk<number>
const name = chunk("Stunk"); // Chunk<string>
const user = chunk({ name: "Fola", age: 25 }); // Chunk<{ name: string; age: number }>

// TypeScript will catch this at compile time:
count.set("hello"); // ❌ Argument of type 'string' is not assignable to 'number'

You can also opt into strict mode to catch accidental shape mutations at runtime in development:

const user = chunk({ name: "Fola", age: 25 }, { strict: true });

// In development — throws immediately:
user.set({ name: "Fola", age: 25, role: "admin" });
// 🚨 Stunk: [chunk_0] Unexpected keys in set(): role.

Requirements

RequirementVersion
TypeScript^5.0.0 (optional but recommended)
React^17.0.0 || ^18.0.0 || ^19.0.0 (optional)
Vue^3.5.13 (optional, WIP)
Node.jsAny modern version supporting ES2020
BundlerVite, Webpack, Rollup, esbuild — anything ESM-compatible

Stunk outputs both ESM and CJS formats, so it works in any modern JavaScript environment — browser, Node.js, or edge runtimes.


What's next?

On this page