{"id":22454344,"url":"https://github.com/littensy/reflex","last_synced_at":"2025-04-04T22:08:36.721Z","repository":{"id":143435380,"uuid":"615611609","full_name":"littensy/reflex","owner":"littensy","description":"♻️ An all-in-one state container for Roblox","archived":false,"fork":false,"pushed_at":"2024-12-10T23:21:59.000Z","size":5148,"stargazers_count":85,"open_issues_count":2,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-28T21:09:17.587Z","etag":null,"topics":["roblox","state-management","typescript"],"latest_commit_sha":null,"homepage":"https://littensy.github.io/reflex/","language":"Lua","has_issues":true,"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/littensy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-18T06:30:08.000Z","updated_at":"2025-03-14T01:54:51.000Z","dependencies_parsed_at":"2024-06-19T11:28:24.231Z","dependency_job_id":"f9c69206-0db4-4bef-ac68-9bd06f180cb4","html_url":"https://github.com/littensy/reflex","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/littensy%2Freflex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/littensy%2Freflex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/littensy%2Freflex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/littensy%2Freflex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/littensy","download_url":"https://codeload.github.com/littensy/reflex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256115,"owners_count":20909240,"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","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":["roblox","state-management","typescript"],"created_at":"2024-12-06T07:07:31.436Z","updated_at":"2025-04-04T22:08:36.700Z","avatar_url":"https://github.com/littensy.png","language":"Lua","readme":"\u003ch1 align=\"center\"\u003e\n\t\u003ca href=\"https://www.npmjs.com/package/@rbxts/reflex\"\u003e\n\t\t\u003cimg src=\"public/logo.png\" alt=\"Reflex\" width=\"200\" /\u003e\n\t\u003c/a\u003e\n\t\u003cbr /\u003e\n\t\u003cb\u003eReflex\u003c/b\u003e\n\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/littensy/reflex/ci.yml?branch=master\u0026style=for-the-badge\u0026logo=github)\n[![npm version](https://img.shields.io/npm/v/@rbxts/reflex.svg?style=for-the-badge\u0026logo=npm)](https://www.npmjs.com/package/@rbxts/reflex)\n[![npm downloads](https://img.shields.io/npm/dt/@rbxts/reflex.svg?style=for-the-badge\u0026logo=npm)](https://www.npmjs.com/package/@rbxts/reflex)\n[![GitHub license](https://img.shields.io/github/license/littensy/reflex?style=for-the-badge)](LICENSE.md)\n\n\u003c/div\u003e\n\n---\n\n\u0026nbsp;\n\n## ♻️ Reflex\n\n**Reflex** is a simple state container inspired by [Rodux](https://github.com/roblox/rodux) and [Silo](https://github.com/sleitnick/rbxts-silo), designed to be an all-in-one solution for managing and reacting to state in Roblox games.\n\nYou can use Reflex with Roact on the client with [`@rbxts/roact-reflex`](https://npmjs.com/package/@rbxts/roact-reflex), or use it to manage your game's state on the server.\n\n\u0026nbsp;\n\n## 📦 Installation\n\nThis package is available for Roblox TypeScript and [Wally](https://wally.run/package/littensy/reflex).\n\n```bash\nnpm install @rbxts/reflex\nyarn add @rbxts/reflex\npnpm add @rbxts/reflex\n```\n\n\u0026nbsp;\n\n## 📚 Quick Start\n\n[Take me to the documentation →](https://littensy.github.io/reflex)\n\n### ⚡️ Start using Reflex\n\nWhere Rodux uses stores, reducers, and actions, Reflex revolves around **actions** and [**producers**](https://littensy.github.io/reflex/docs/reference/reflex/producer). Create a producer with an initial state and a set of actions, and you're ready to go.\n\n```ts\nimport { createProducer } from \"@rbxts/reflex\";\n\ninterface State {\n\tcount: number;\n}\n\nconst initialState: State = {\n\tcount: 0,\n};\n\nconst producer = createProducer(initialState, {\n\tincrement: (state) =\u003e ({ ...state, count: state.count + 1 }),\n\treset: (state) =\u003e ({ ...state, count: 0 }),\n});\n```\n\n### ✨ Use your producer anywhere\n\nReflex was designed to make managing your state simple and straightforward. Dispatch actions by calling the action directly, and read \u0026 subscribe to state with selectors.\n\n```ts\nconst selectCount = (state: State) =\u003e state.count;\n\nproducer.subscribe(selectCount, (count) =\u003e {\n\tprint(`The count is now ${count}`);\n});\n\nproducer.increment(); // The count is now 1\n```\n\n\u0026nbsp;\n\n## ⚛️ Roact Reflex\n\nThe official bindings for Reflex and Roact Hooked are available under [`@rbxts/roact-reflex`](https://www.npmjs.com/package/@rbxts/roact-reflex). Currently, there is no support for Luau projects.\n\n[See the source code on GitHub →](https://github.com/littensy/roact-reflex)\n\n### ⚙️ Components\n\nRoact Reflex allows you to use your root producer from Roact function components. It exposes a component that you can use to specify the producer for Hooks to use:\n\n-   [`\u003cReflexProvider\u003e`](https://littensy.github.io/reflex/docs/reference/roact-reflex/reflex-provider) enables Reflex Hooks for a producer.\n\n```tsx\nRoact.mount(\n\t\u003cReflexProvider producer={producer}\u003e\n\t\t\u003cApp /\u003e\n\t\u003c/ReflexProvider\u003e,\n\tplayerGui,\n);\n```\n\n### 🪝 Context Hooks\n\nYou can use Hooks to read and subscribe to state, or to dispatch actions. Use these Hooks in function components that are wrapped in a [`\u003cReflexProvider\u003e`](https://littensy.github.io/reflex/docs/reference/roact-reflex/reflex-provider).\n\nUse these Hooks to access the root producer and dispatch actions:\n\n-   [`useProducer`](https://littensy.github.io/reflex/docs/reference/roact-reflex/use-producer) lets components read and dispatch actions to the root producer.\n\n```tsx\nfunction Button() {\n    const { increment } = useProducer();\n    // ...\n```\n\n### 🪝 State Hooks\n\nUse these Hooks to read and subscribe to state:\n\n-   [`useSelector`](https://littensy.github.io/reflex/docs/reference/roact-reflex/use-selector) lets a component subscribe to a Reflex producer.\n-   [`useSelectorCreator`](https://littensy.github.io/reflex/docs/reference/roact-reflex/use-selector-creator) lets you call `useSelector` with a [selector factory](https://littensy.github.io/reflex/docs/reference/reflex/create-selector#selector-factories).\n\n```tsx\nfunction Counter() {\n    const count = useSelector((state) =\u003e state.count);\n    // ...\n```\n\n\u0026nbsp;\n\n## 📝 License\n\nReflex is licensed under the [MIT License](LICENSE.md).\n","funding_links":[],"categories":["State Management"],"sub_categories":["Reflex \u003cimg src=\"luau.svg\" width=\"18px\" /\u003e\u003cimg src=\"roblox-ts.svg\" width=\"18px\" /\u003e"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flittensy%2Freflex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flittensy%2Freflex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flittensy%2Freflex/lists"}