@cervello/react

中文文档
6.0.0发布于 2026/09/29MITTypeScriptESM + CJS零依赖近 30 天下载 2212

🤯 Simple, reactive, tiny and performant state-management library

原始使用文档
文档目录5 节
  1. 🚀 Features
  2. 📦 Install
  3. 💻 Quick Usage
  4. 💡 Good to know
  5. To see more in depth explanations or API references and mor…

Cervello

npm version bundle-size

🤯 Simple, reactive, tiny and performant state-management library for React (just 1.5kb)



📖 Documentation website


🚀 Features

  • ⚛️ Reactive with store object changes (nested properties too 🚀!!)
  • ✅ Simple & minimalistic API
  • 🚀 Batched updates and optimized re-renders
  • 🐨 Lazy listen nested properties
  • 🔒 Immutable changes
  • 🔑 Typescript support

📦 Install

# NPM
npm install @cervello/react

# PNPM
pnpm add @cervello/react

# YARN
yarn add @cervello/react

💻 Quick Usage

It's as simple as reassign a new value to the store properties.
It will notify all the components using useStore hook to re-render with the new value.

// - store-example.ts
import { cervello } from '@cervello/react'

export const {
  store,       // Object with reactive changes
  useStore,    // Hook to listen for store or partial store changes
  reset,       // Function to reset the store to initial value
} = cervello({
  fullName: 'Cervello Store',
  address: {
    city: 'Huelva',
    /* ... */
  },
})


// Change value from anywhere
store.address.city = 'Sevilla'


// Listen for changes from components
function Address() {
  const { address } = useStore()
  return (<p>City: {address.city}</p>)
}


// Just listen for changes in the `city` property
const AddressWithSelector = () => {
  const { address } = useStore({
    select: ['address.city']
  })

  return (<p>City: {address.city}</p>)
}

💡 Good to know

  • Batched changes: mutations are coalesced and flushed once per microtask. onChange/afterChange receive the whole batch as an array (don't mutate it — it may be shared between subscribers).
  • No spurious updates: assigning content-equal values (same primitive, or a plain object with the same content — key order doesn't matter) does not notify or re-render. Arrays, nonReactive objects and React elements always notify. A component that already rendered after a write (e.g. a handler that calls setState and then writes to the store) is not re-rendered again by that write.
  • Nested objects are live views: const { address } = useStore() (or const a = store.address) keeps pointing at the store's current data even after store.address = {...}, store.$value = {...} or reset(), so writing through it always updates the store. If its path stops being an object (store.address = null), writes through the old handle are dropped.
  • $value is always a copy: reading store.$value returns a deep clone, and store.$value = obj (like cervello(obj) and reset()) stores a deep clone of obj — mutating obj afterwards does not touch the store. Prefer { ...store.$value, x } over { ...store, x } when building a new value.
  • Hot components: pass select: ['path', 'nested.*'] to useStore so the component only re-renders for those paths; without it, it re-renders on every store change. Exact paths match their own writes; 'address.*' also matches anything nested under address. When an ancestor is reassigned (store.address = {...}, store.$value = {...} or reset()), the selected slice is compared by content and the component only re-renders if it actually changed. Rule: a component must only read the paths it selects — a non-selected field read in render is never refreshed.
  • afterChange fires on every emission: field writes, whole-store replacement (store.$value = ..., reset()) and initialValue seeds — content-equal writes never emit, so they never fire it either. For seeds it is deferred to a microtask (never inside a React render). A subscriber (onChange) that throws does not stop the other subscribers nor later updates: the error is re-thrown asynchronously.
  • StrictMode: initialValue is render-phase code (double-invoked in dev — keep it idempotent) and setValueOnMount runs on each effect mount, per React's contract.
  • SSR: the store is module-scoped. For per-request isolation, call cervello() per request and share it via context.
  • Complex values (Date, Map, Set, class instances, circular refs): wrap them with nonReactive(...) — they are kept intact (and restored by reset()) but don't trigger reactivity.



To see more in depth explanations or API references and more examples: 📖 Documentation website



Created with Typescript! ⚡ and latin music 🎺🎵

版本与发布记录

@cervello/react 共发布 69 个版本,首次发布于 2022/07/25;过去 12 个月发布了 3 个版本。

版本发布日期距今
6.0.0latest2026/09/291 个月前
5.5.02026/04/296 个月前
5.4.12025/11/2011 个月前
5.4.02025/07/091.3 年前
5.4.0-beta.3beta2025/07/071.3 年前
5.4.0-beta.22025/07/071.3 年前

关于 @cervello/react 的常见问题

@cervello/react 是什么?

🤯 Simple, reactive, tiny and performant state-management library

如何安装 @cervello/react?

在项目目录运行 npm install @cervello/react,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>= 18.2.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cervello/react 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cervello/react 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cervello/react 可以商用吗?

@cervello/react 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cervello/react 的下载量有多少?

根据 npm 官方下载统计,@cervello/react 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,212 次,日均约 74 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cervello/react 还在维护吗?

最新版本 6.0.0 发布于 2026/09/29(1 个月前);至今共发布 69 个版本,其中过去 12 个月发布了 3 个;首次发布于 2022/07/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。