Getting Started
Changelog
A history of Stunk releases, API changes, and what's coming next.
Stunk follows semantic versioning. Minor and patch releases are fully backward-compatible. Breaking changes only happen in major versions.
v3.0.0 — alpha.2 (Current)
Alpha release. Bundle size: 3.32kB gzipped (core + React + Query).
v3 is in active development. APIs are stable but may change before the final release. For production use, see v2.8.1.
What's new in v3
Core (stunk)
peek()— read a chunk value without registering it as a tracked dependencystrictmode onChunkConfig— throws or warns on unknown keys inset()in developmentnullis now a valid chunk value (undefinedstill forbidden)ReadOnlyChunk<T>—derive()now returns a proper read-only type at the TypeScript leveltrackDependenciesexported — for building custom reactive primitivesvalidateObjectShapeimproved — no longer warns onundefined → TorT → nulltransitions
Computed (redesigned)
- Auto-tracks dependencies via
.get()calls — no dependency arrays needed - Lazy evaluation with eager recompute when subscribers are active
isDirty()andrecompute()for manual controlpeek()insidecomputed()reads without tracking- Diamond dependency pattern handled correctly — subscribers notified once
// v2
const total = computed([price, quantity], (p, q) => p * q);
// v3
const total = computed(() => price.get() * quantity.get());Query — new subpath stunk/query
asyncChunk— reactive async state with loading, error, data, lastFetchedinfiniteAsyncChunk— accumulate-mode pagination for infinite scrollcombineAsyncChunks— unified loading/error/data across multiple async chunkskeyoption — request deduplication, concurrent calls share one in-flight requestkeepPreviousData+isPlaceholderData— no UI flicker on param changesonSuccess/onErrorcallbacksenabledas boolean or() => boolean— dynamic disablingsetParamswithnullclearing individual keys,clearParams()to wipe allrefetchOnWindowFocus,refetchInterval,staleTime,cacheTimeforceCleanup()+ ref-countedcleanup()- Full pagination —
nextPage,prevPage,goToPage,resetPagination - SSR-safe — all
windowaccess guarded
Middleware (stunk/middleware)
history(renamed fromwithHistory) —reset()now clears the history stackskipDuplicates: true— strict equality only;'shallow'— shallow equality for objectspersist(renamed fromwithPersistence) —clearStorage()added,onErrorcalled on type mismatches, array vs object type mismatch detection
React (stunk/react)
useAsyncChunk— rewritten: single effect, Rules of Hooks compliant, exposesisPlaceholderDataandclearParamsuseInfiniteAsyncChunk— stableIntersectionObserver, SSR-safe, correctisFetchingMoreuseDerive,useComputed,useChunkProperty,useChunkValues— removed (useuseChunkValue(computed(...))instead)
Breaking changes from v2
| Change | v2 | v3 |
|---|---|---|
computed() API | computed([deps], fn) | computed(() => fn) |
withHistory | import { withHistory } | import { history } |
withPersistence | import { withPersistence } | import { persist } |
asyncChunk import | stunk | stunk/query |
useDerive / useComputed | available | removed |
subscribe fires on subscribe | yes | no — only on change |
null as chunk value | forbidden | allowed |
v2.8.1 — Stable
Latest stable release. Bundle size: 2.95kB gzipped (core + React).
What's in v2
Core (stunk)
chunk()— atomic state primitive withget(),set(),reset(),destroy(),subscribe(),derive()computed()— derive state from multiple chunks with dependency arrays andisDirty()trackingselect()— read-only derived chunk with optional shallow equality (useShallowEqual)asyncChunk()— async state with built-inloading,error,data, andreloadinfiniteAsyncChunk()— paginated / infinite-scroll async statebatch()— group multiple state updates into a single render cycle
Middleware (stunk/middleware)
logger— logs everyset()callwithHistory()— undo/redo history (undo,redo,canUndo,canRedo,getHistory,clearHistory,maxHistory)withPersistence()— localStorage persistence with customserialize/deserializenonNegativeValidator— throws if a numeric value goes below zero
React (stunk/react)
useChunk— read and write a chunk reactivelyuseChunkValue— read-only subscriptionuseDerive— derive a value from a single chunkuseComputed— compute a value from multiple chunksuseAsyncChunk— async state hookuseInfiniteAsyncChunk— infinite scroll hook
v1 → v2 Migration
set() and update() merged
// v1
count.set(10);
count.update((n) => n + 1);
// v2+
count.set(10);
count.set((n) => n + 1); // update() removedRelease History
| Version | Status | Highlights |
|---|---|---|
3.0.0-alpha | 🚧 Alpha | Computed redesign, stunk/query, strict mode, null values |
2.8.1 | ✅ Stable | Latest stable, 2.95kB gzipped |
2.x | ✅ Stable | Full React integration, async, middleware, time travel |
1.x | ⚠️ Deprecated | Early API, no longer supported |