Core Concepts
Valdres has four building blocks: atoms, selectors, families, and stores. Understanding these gets you 90% of the way.
Atoms
An atom is the smallest unit of state. Create one with a default value:
import { atom } from "valdres"
const countAtom = atom(0)
const nameAtom = atom("world")
Atoms are just descriptions — they don't hold values themselves. Values live in a store.
Selectors
A selector derives a value from one or more atoms (or other selectors). It re-computes automatically when its dependencies change:
import { selector } from "valdres"
const doubledCount = selector(get => get(countAtom) * 2)
const greeting = selector(get => `Hello, ${get(nameAtom)}!`)
Selectors are read-only by default. They're great for computed or filtered views of your state.
Families
When you need many atoms or selectors indexed by a key — a list of users, a grid of cells, todo items by ID — use a family:
import { atomFamily, selectorFamily } from "valdres"
const userAtom = atomFamily(userId => ({ id: userId, name: "" }))
const userLabel = selectorFamily(userId =>
get => `User: ${get(userAtom(userId)).name}`
)
Calling userAtom("abc") returns the atom for that specific key. Atoms are created lazily on first access.
Stores
A store holds all the atom values. You can create one explicitly, or let your framework adapter create a default one:
import { store } from "valdres"
const myStore = store()
myStore.set(countAtom, 42)
console.log(myStore.get(countAtom)) // 42
// Subscribe to changes
myStore.sub(countAtom, value => {
console.log("count changed:", value)
})
In framework adapters, a store is typically provided via context (e.g. <Provider> in React, createValdres() in Vue). If you don't provide one, a default global store is used.
Putting It Together
import { atom, selector, store } from "valdres"
const todosAtom = atom([])
const completedCount = selector(get =>
get(todosAtom).filter(t => t.done).length
)
const myStore = store()
myStore.set(todosAtom, [
{ text: "Learn Valdres", done: true },
{ text: "Build something", done: false },
])
console.log(myStore.get(completedCount)) // 1
The core valdres package is framework-agnostic. Framework adapters like valdres-react add hooks and components that subscribe to store changes and trigger re-renders efficiently.