{"id":13452076,"url":"https://github.com/jamiebuilds/bey","last_synced_at":"2025-08-18T13:04:04.633Z","repository":{"id":66094766,"uuid":"133564772","full_name":"jamiebuilds/bey","owner":"jamiebuilds","description":"Simple immutable state for React using Immer","archived":false,"fork":false,"pushed_at":"2019-02-08T17:36:15.000Z","size":72,"stargazers_count":257,"open_issues_count":2,"forks_count":9,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-08-18T13:04:00.333Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jamiebuilds.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-05-15T19:39:44.000Z","updated_at":"2025-07-17T16:50:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"633f7288-cba8-48f7-9966-afc9a2a1cdbe","html_url":"https://github.com/jamiebuilds/bey","commit_stats":{"total_commits":13,"total_committers":3,"mean_commits":4.333333333333333,"dds":"0.15384615384615385","last_synced_commit":"ae73c4458c199df17d2c9090a130b646caa7451d"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/jamiebuilds/bey","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamiebuilds%2Fbey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamiebuilds%2Fbey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamiebuilds%2Fbey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamiebuilds%2Fbey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jamiebuilds","download_url":"https://codeload.github.com/jamiebuilds/bey/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jamiebuilds%2Fbey/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270996917,"owners_count":24681940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T07:01:12.074Z","updated_at":"2025-08-18T13:04:04.607Z","avatar_url":"https://github.com/jamiebuilds.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# bey\n\n\u003e Simple immutable state for React using [Immer](https://github.com/mweststrate/immer)\n\n- **~700B minified and gzipped** (not including React \u0026 Immer)\n- Try it out alongside other state solutions\n- Heavily inspired by [react-copy-write](https://github.com/aweary/react-copy-write)\n\n## Install\n\n```sh\nyarn add bey\n```\n\n## Example\n\n```js\nimport React from 'react';\nimport { render } from 'react-dom';\nimport { state, update, Subscribe } from 'bey';\n\nlet counter = state({\n  count: 0,\n});\n\nfunction increment() {\n  update(counter, state =\u003e { state.count++ });\n}\n\nfunction decrement() {\n  update(counter, state =\u003e { state.count-- });\n}\n\nfunction Counter() {\n  return (\n    \u003cSubscribe to={counter} on={state =\u003e state.count}\u003e\n      {count =\u003e (\n        \u003cdiv\u003e\n          \u003cbutton onClick={decrement}\u003e-\u003c/button\u003e\n          \u003cspan\u003e{count}\u003c/span\u003e\n          \u003cbutton onClick={increment}\u003e+\u003c/button\u003e\n        \u003c/div\u003e\n      )}\n    \u003c/Subscribe\u003e\n  );\n}\n\nrender(\u003cCounter/\u003e, window.root);\n```\n\nRun this example locally by [cloning the repo](https://help.github.com/articles/cloning-a-repository/)\nand running `yarn example` in the root directory.\n\n## Guide\n\n### `state()`\n\nFirst you'll need to create some state containers for your app.\n\n```js\nlet counter = state({\n  count: 0\n});\n```\n\nCall `state()` with your initial state and you're good to go.\n\nThis returns a small object which we can subscribe to, update, and get\nthe current state from.\n\n### `update()`\n\nYou'll want to create some \"actions\" that will update your state when\ncalled. These should just be plain functions that call `update()` inside.\n\n```js\nlet counter = state({\n  count: 0\n});\n\nfunction increment() {\n  update(counter, state =\u003e { state.count++; });\n}\n\nfunction decrement() {\n  update(counter, state =\u003e { state.count--; });\n}\n```\n\nWhen you call `update()` you'll pass your state container and an \"updater\"\nfunction. Inside the \"updater\" function is just passed through to\n[Immer](https://github.com/mweststrate/immer) (You'll want to read about that\nworks).\n\nYou'll notice that inside the updater function you can just mutate whatever you\nwant. Don't mutate outside of the updater function though.\n\n### `\u003cSubscribe/\u003e`\n\nFinally, you'll need a way to subscribe to state updates and re-render your\ntree.\n\n```js\nfunction Counter() {\n  return (\n    \u003cSubscribe to={counter}\u003e\n      {state =\u003e \u003cspan\u003e{state.count}\u003c/span\u003e}\n    \u003c/Subscribe\u003e\n  );\n}\n```\n\nIf you only need part of your state, you get pass an optional `on` prop which\nselects just the state you care about and passes it through to the children\nfunction.\n\n```js\nfunction Counter() {\n  return (\n    \u003cSubscribe to={counter} on={state =\u003e state.count}\u003e\n      {count =\u003e \u003cspan\u003e{count}\u003c/span\u003e}\n    \u003c/Subscribe\u003e\n  );\n}\n```\n\nThis also acts as an optimization when you have a large state object but only\nneed to re-render when a nested value in that state object is updated.\n\nIf you need multiple values, you can return an object:\n\n```js\n\u003cSubscribe to={user} on={state =\u003e ({ name: state.name, username: state.username })}\u003e\n  {({ name, username }) =\u003e \u003cspan\u003e{name} (@{username})\u003c/span\u003e}\n\u003c/Subscribe\u003e\n```\n\nThe same optimizations will apply using the same shallow equality check that\nReact uses.\n\n### Calling actions\n\nActions can be called at any time from any part of your app.\n\n```js\nlet counter = state({ count: 0 });\n\nfunction increment() {\n  update(counter, state =\u003e { state.count++; });\n}\n\nfunction Increment() {\n  return \u003cbutton onClick={increment}\u003e+\u003c/button\u003e;\n}\n```\n\n### Multiple instances of containers\n\nIf you need to create multiple instances of containers, wrap your `state()`\ncall in a factory:\n\n```js\nlet createCounter = () =\u003e {\n  return state({ count: 0 });\n};\n```\n\nRemember that your methods for updating state are just functions, don't be\nafraid to write them however you need. So here we can pass the state object we\nare updating as a parameter.\n\n```js\nfunction increment(counter) {\n  update(counter, state =\u003e { state.count++; });\n}\n\nfunction decrement(counter) {\n  update(counter, state =\u003e { state.count--; });\n}\n```\n\nThen inside your components where you call those methods, pass the state\nobjects in:\n\n```js\nfunction Counter(props) {\n  return (\n    \u003cSubscribe to={props.counter} on={state =\u003e state.count}\u003e\n      {count =\u003e (\n        \u003cdiv\u003e\n          \u003cbutton onClick={() =\u003e decrement(props.counter)}\u003e-\u003c/button\u003e\n          \u003cspan\u003e{count}\u003c/span\u003e\n          \u003cbutton onClick={() =\u003e increment(props.counter)}\u003e+\u003c/button\u003e\n        \u003c/div\u003e\n      )}\n    \u003c/Subscribe\u003e\n  );\n}\n\nfunction Counters(props) {\n  return (\n    \u003cdiv\u003e\n      \u003cCounter counter={createCounter()}/\u003e\n      \u003cCounter counter={createCounter()}/\u003e\n    \u003c/div\u003e\n  );\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamiebuilds%2Fbey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjamiebuilds%2Fbey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjamiebuilds%2Fbey/lists"}