npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

chrono-state-z

v2.1.0

Published

Intent-first, logic-centric reactive state runtime with atoms, computed, async state, effects, and deterministic scheduling. React-agnostic core.

Readme

⏱️ chrono-state-z

NPM Downloads

LIVE EXAMPLE


chrono-state-z is a reactive, intent-first state runtime designed to keep business logic outside React.

It provides atoms, computed values, async state, effects, scheduling, with a headless core and thin React bindings.

React renders state. Logic lives elsewhere.


✨ Why chrono-state-z?

Use chrono-state-z when you need:

  • Predictable state & side-effects
  • Complex async flows (fetch → invalidate → retry)
  • Logic reusable outside React (tests, workers, backend)
  • Fine-grained reactivity (no global rerenders)
  • Clear separation between logic and view

🧠 Mental Model

  • Atom — small reactive state unit
  • Computed — derived value, cached and reactive
  • AsyncAtom — async state with suspense-style read
  • Effect — reactive side-effect runner
  • Scheduler — priority-based execution control
  • Store / Intent — intent-driven state orchestration
  • React hooks — thin bindings over the headless core

📦 Installation

# npm install react ## for react
npm install intentx-core-z chrono-state-z

🔹 Core Usage

Atom & Computed

import { atom, computed } from 'chrono-state-z'

const count = atom(0)
const double = computed(() => count() * 2)

count.set(5)

console.log(count())   // 5
console.log(double())  // 10

Reactive Effects

import { atom, effect } from 'chrono-state-z'

const count = atom(0)

const dispose = effect(() => {
  console.log('Count changed:', count())
})

count.set(1) // logs: Count changed: 1

dispose()

🔹 Async State

AsyncAtom

import { asyncAtom } from 'chrono-state-z'

const user = asyncAtom(async () => {
  const res = await fetch('/api/user')
  return res.json()
})

await user.load()

const u = user()

Invalidate & refetch:

user.invalidate()
user.invalidate('low')

AsyncComputed

import { asyncComputed, atom } from 'chrono-state-z'

const count = atom(2)

const doubleAsync = asyncComputed(async () => {
  await new Promise(r => setTimeout(r, 50))
  return count() * 2
})

await doubleAsync()

🔹 Transactions (Batch updates)

import { atom, transaction } from 'chrono-state-z'

const a = atom(1)
const b = atom(2)

transaction(() => {
  a.set(10)
  b.set(20)
})

console.log(a(), b())

🔹 Store & Intent (Logic Layer)

import { createStore } from 'chrono-state-z'

type State = {
  saving: boolean
  value: string
}

const logic = createStore<State>({
  saving: false,
  value: ''
})

logic.on('SAVE', async ({ state, setState }) => {
  setState(s => { s.saving = true })

  await fakeApiSave(state().value)

  setState(s => { s.saving = false })
})

Emit intent:

await logic.emit('SAVE')

🔹 React Integration

useAtom

import { atom, useAtom } from 'chrono-state-z'

const count = atom(0)

function Counter() {
  const value = useAtom(count)

  return (
    <button onClick={() => count.set(value + 1)}>
      Count: {value}
    </button>
  )
}

useComputed

import { computed, useComputed } from 'chrono-state-z'

const total = computed(() => price() * qty())

function TotalView() {
  const value = useComputed(total)
  return <div>Total: {value}</div>
}

useAtomSelector

// atom() returns a callable reactive value
const user = atom({ id: 1, name: 'Alice', age: 20 })

function Username() {
  const name = useAtomSelector(user, u => u.name)
  return <span>{name}</span>
}

useStore

import { useStore } from 'chrono-state-z'
import type { Store } from 'chrono-state-z'

function StoreView({ store }: { store: Store<any> }) {
  const state = useStore(store)
  return <pre>{JSON.stringify(state, null, 2)}</pre>
}

useStoreSelector

// Only re-renders when saving changes, not the whole store.
import { useStoreSelector } from 'chrono-state-z'

function SavingBadge({ store }) {
  const saving = useStoreSelector(store, s => s.saving)
  // const saving = useStoreSelector(
  //   store,
  //   s => s.meta,
  //   shallowEqual
  // )
  return saving ? 'Saving...' : 'Idle'
}
  • selector should be pure and stable.
  • If you need dynamic selection, memoize the selector.

useWatch

import { useWatch } from 'chrono-state-z'

function AuthGuard() {
  useWatch(
    () => user(),
    (u) => {
      if (u?.role === 'admin') {
        redirect('/admin')
      }
    }
  )

  return null
}

AsyncAtom

const user = asyncAtom(fetchUser)

// load explicitly
await user.load()

// read value (throws / suspends if not ready)
const u = user()

🧩 Architecture Pattern

import { asyncAtom, computed } from 'chrono-state-z'

export function createUserLogic() {
  const user = asyncAtom(fetchUser)
  const name = computed(() => user()?.name ?? 'Guest')

  return {
    user,
    name,
    reload: () => user.invalidate()
  }
}
function UserView({ logic }) {
  const user = useAtom(logic.user)
  const name = useComputed(() => logic.name())

  return (
    <>
      <div>Hello {name}</div>
      <button onClick={logic.reload}>Reload</button>
    </>
  )
}

📊 Comparison with Other Libraries

| Feature | chrono-state-z | Redux | Zustand | Jotai | |---------------------------|---------------- |-------|--------- |------- | | Fine-grained reactivity | ✅ | ❌ | ⚠️ | ✅ | | Async primitives | ✅ | ⚠️ | ❌ | ⚠️ | | Intent / effect layer | ✅ | ⚠️ | ❌ | ❌ | | Scheduler / priority | ✅ | ❌ | ❌ | ❌ | | Headless (non-React) core | ✅ | ❌ | ⚠️ | ❌ | | Testability | ✅ | ⚠️ | ⚠️ | ❌ |


🚫 Anti-patterns

  • Putting business logic inside React components
  • Mutating atom values directly
  • Coupling domain logic to UI events
  • Skipping computed / effects for orchestration

🧠 Philosophy

  • Logic lives outside React
  • Deterministic, testable state
  • Effects are explicit and traceable
  • UI is a pure projection of state

📜 License

MIT