{"id":31753289,"url":"https://github.com/shahabyazdi/rosma","last_synced_at":"2025-10-09T17:44:43.741Z","repository":{"id":65547394,"uuid":"594286534","full_name":"shahabyazdi/rosma","owner":"shahabyazdi","description":"Simple and easy-to-use state management for React.","archived":false,"fork":false,"pushed_at":"2024-08-18T07:28:47.000Z","size":699,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-25T03:19:50.198Z","etag":null,"topics":["management","react","react-native","reactjs","rosma","state","state-management"],"latest_commit_sha":null,"homepage":"https://rosma.dev/","language":"TypeScript","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/shahabyazdi.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":"2023-01-28T03:58:53.000Z","updated_at":"2024-10-19T11:16:53.000Z","dependencies_parsed_at":"2023-11-21T16:51:38.425Z","dependency_job_id":null,"html_url":"https://github.com/shahabyazdi/rosma","commit_stats":{"total_commits":15,"total_committers":1,"mean_commits":15.0,"dds":0.0,"last_synced_commit":"1b1db6d6f90ef3e7b904b53ac003a8ddc97d08ed"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/shahabyazdi/rosma","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahabyazdi%2Frosma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahabyazdi%2Frosma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahabyazdi%2Frosma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahabyazdi%2Frosma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shahabyazdi","download_url":"https://codeload.github.com/shahabyazdi/rosma/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shahabyazdi%2Frosma/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001831,"owners_count":26083197,"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-10-09T02:00:07.460Z","response_time":59,"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":["management","react","react-native","reactjs","rosma","state","state-management"],"created_at":"2025-10-09T17:44:38.240Z","updated_at":"2025-10-09T17:44:43.734Z","avatar_url":"https://github.com/shahabyazdi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rosma\n\nSimple and easy-to-use global state management for React. no need for provider, reducer or nothing else!\n\n# Installation\n\n```bash\nnpm i rosma\n```\n\n# Documentation\n\nhttps://rosma.dev/\n\n## Counter app\n\n```javascript\nimport { useObserver } from 'rosma';\n\nexport default function Counter() {\n  const { count, setCount } = useObserver(0);\n\n  return \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e{count}\u003c/button\u003e;\n}\n```\n\n### No order for variables\n\n```javascript\nimport { useObserver } from 'rosma';\n\nexport default function Counter() {\n  const { setCount, count } = useObserver(0);\n\n  return \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e{count}\u003c/button\u003e;\n}\n```\n\nThe only concept that must be notice is that you must add a 'set' to the beginning of the setter name of the destructed variable.\n\nFor example if you want a setter method for the 'count' variable, you should name that setter as 'setCount'.\n\nAlso, all the destructed variables are case insensitive\n\n```javascript\nimport { useObserver } from 'rosma';\n\nexport default function Counter() {\n  const { CouNt, setcOunT } = useObserver(0);\n\n  return \u003cbutton onClick={() =\u003e setcOunT(Count + 1)}\u003e{CouNt}\u003c/button\u003e;\n}\n```\n\n### Multiple destructuring\n\nDestruct all the variables you want at once\n\n```javascript\nimport { useObserver } from 'rosma';\n\nexport default function Counts() {\n  const { count, setCount, count1, setCount1 } = useObserver(0);\n\n  return (\n    \u003c\u003e\n      \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e{count}\u003c/button\u003e\n      \u003cbutton onClick={() =\u003e setCount1(count1 + 1)}\u003e{count1}\u003c/button\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Different initial values\n\nIn the example above, all the variables take the initial value of 0. to avoid this, one of the following methods can be used:\n\n- Define the initial values separately\n\n```javascript\nimport { useObserver } from 'rosma';\n\nexport default function Counts() {\n  const { count, setCount } = useObserver(10);\n  const { count1, setCount1 } = useObserver(20);\n\n  return (\n    \u003c\u003e\n      \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e{count}\u003c/button\u003e\n      \u003cbutton onClick={() =\u003e setCount1(count1 + 1)}\u003e{count1}\u003c/button\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n- Define the initial values at once\n\nIf you want to set the initial values and also destruct them at once, you can set the initial values directly from the observer.\n\n```javascript\nimport { observer, useObserver } from 'rosma';\n\nobserver.set({ count: 10, count1: 20 });\n\nexport default function Counts() {\n  const { count, setCount, count1, setCount1 } = useObserver();\n\n  return (\n    \u003c\u003e\n      \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e{count}\u003c/button\u003e\n      \u003cbutton onClick={() =\u003e setCount1(count1 + 1)}\u003e{count1}\u003c/button\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n## Notes app\n\n```javascript\nimport { useObserver } from 'rosma';\n\nexport default function Note() {\n  const { note = '', setNote, notes = [], setNotes } = useObserver();\n\n  return (\n    \u003c\u003e\n      \u003cinput value={note} onChange={(e) =\u003e setNote(e.target.value)} placeholder=\"write something\" /\u003e\n      \u003cbutton\n        onClick={() =\u003e {\n          setNotes(notes.concat(note));\n          setNote('');\n        }}\n      \u003e\n        Add\n      \u003c/button\u003e\n      \u003cul\u003e\n        {notes.map((note, index) =\u003e (\n          \u003cli key={index}\u003e{note}\u003c/li\u003e\n        ))}\n      \u003c/ul\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Avoiding extra rerender\n\nIf you want the entire main component not to be re-rendered with state changes, you can easily split the elements of the main component into smaller components using the withState method.\n\n```javascript\nimport { withState } from 'rosma';\n\nconst Input = withState(({ note = '', setNote }) =\u003e \u003cinput value={note} onChange={(e) =\u003e setNote(e.target.value)} placeholder=\"write something\" /\u003e);\n\nconst Button = withState(({ note, setNotes, setNote }) =\u003e (\n  \u003cbutton\n    onClick={() =\u003e {\n      setNotes((notes = []) =\u003e notes.concat(note));\n      setNote('');\n    }}\n  \u003e\n    Add\n  \u003c/button\u003e\n));\n\nconst List = withState(({ notes = [] }) =\u003e (\n  \u003cul\u003e\n    {notes.map((note, index) =\u003e (\n      \u003cli key={index}\u003e{note}\u003c/li\u003e\n    ))}\n  \u003c/ul\u003e\n));\n\nexport default function Note() {\n  return (\n    \u003c\u003e\n      \u003cInput /\u003e\n      \u003cButton /\u003e\n      \u003cList /\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Further optimization\n\nTo avoid extra rendering, you can read the values directly from the observer. In the example above, the Button component is re-rendered every time that the 'note' variable is changed. But you can avoid this extra rendering by reading the 'note' value from the observer.\n\n```javascript\nimport { observer, withState } from 'rosma';\n\nconst Input = withState(({ note = '', setNote }) =\u003e \u003cinput value={note} onChange={(e) =\u003e setNote(e.target.value)} placeholder=\"write something\" /\u003e);\n\nconst Button = withState(({ setNotes, setNote }) =\u003e (\n  \u003cbutton\n    onClick={() =\u003e {\n      setNotes((notes = []) =\u003e notes.concat(observer.get('note')));\n      setNote('');\n    }}\n  \u003e\n    Add\n  \u003c/button\u003e\n));\n\nconst List = withState(({ notes = [] }) =\u003e (\n  \u003cul\u003e\n    {notes.map((note, index) =\u003e (\n      \u003cli key={index}\u003e{note}\u003c/li\u003e\n    ))}\n  \u003c/ul\u003e\n));\n\nexport default function Note() {\n  return (\n    \u003c\u003e\n      \u003cInput /\u003e\n      \u003cButton /\u003e\n      \u003cList /\u003e\n    \u003c/\u003e\n  );\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshahabyazdi%2Frosma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshahabyazdi%2Frosma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshahabyazdi%2Frosma/lists"}