{"id":18700245,"url":"https://github.com/olian04/simply-reactive","last_synced_at":"2025-06-24T10:08:28.690Z","repository":{"id":63737965,"uuid":"561282266","full_name":"Olian04/simply-reactive","owner":"Olian04","description":"A small \u0026 dependency free reactive state management library inspired by Solidjs and Recoiljs.","archived":false,"fork":false,"pushed_at":"2023-06-18T10:03:02.000Z","size":414,"stargazers_count":6,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-21T10:05:39.953Z","etag":null,"topics":["javascript","observer-pattern","reactive-programming","state-management","typescript","typescript-library"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/simply-reactive","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/Olian04.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-03T11:04:01.000Z","updated_at":"2025-01-29T16:52:02.000Z","dependencies_parsed_at":"2024-06-19T06:18:31.016Z","dependency_job_id":"42ca41f5-b391-45e4-bd79-c31f4b709717","html_url":"https://github.com/Olian04/simply-reactive","commit_stats":{"total_commits":121,"total_committers":2,"mean_commits":60.5,"dds":0.06611570247933884,"last_synced_commit":"64186204c6c3c08bece8d8f65840fd84a9d81d12"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Olian04/simply-reactive","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fsimply-reactive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fsimply-reactive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fsimply-reactive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fsimply-reactive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Olian04","download_url":"https://codeload.github.com/Olian04/simply-reactive/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Olian04%2Fsimply-reactive/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261649857,"owners_count":23189753,"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":["javascript","observer-pattern","reactive-programming","state-management","typescript","typescript-library"],"created_at":"2024-11-07T11:36:30.692Z","updated_at":"2025-06-24T10:08:28.672Z","avatar_url":"https://github.com/Olian04.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Latest released version](https://img.shields.io/npm/v/simply-reactive)](https://www.npmjs.com/package/simply-reactive)\n[![Minified and gzipped bundle size](https://img.shields.io/bundlephobia/minzip/simply-reactive)](https://bundlephobia.com/package/simply-reactive)\n![Type support](https://img.shields.io/npm/types/simply-reactive)\n[![Downloads from NPM](https://img.shields.io/npm/dm/simply-reactive?label=downloads%20npm)](https://www.npmjs.com/package/simply-reactive)\n[![Downloads from JSDeliver](https://img.shields.io/jsdelivr/npm/hm/simply-reactive?label=downloads%20jsDelivr)](https://www.jsdelivr.com/package/npm/simply-reactive)\n[![Build status of main branch](https://img.shields.io/circleci/build/github/Olian04/simply-reactive/main?label=test%20%26%20build)](https://app.circleci.com/pipelines/github/Olian04/simply-reactive)\n[![Code percentage covered by tests on main branch](https://codecov.io/gh/Olian04/simply-reactive/branch/main/graph/badge.svg?token=mcsHmshPaF)](https://codecov.io/gh/Olian04/simply-reactive)\n[![MIT licensed](https://img.shields.io/npm/l/simply-reactive)](./LICENSE)\n\n# simply-reactive\n\nSimply-reactive is a [small \u0026 dependency free](https://bundlephobia.com/package/simply-reactive) reactive state management library inspired by [Solidjs](https://github.com/solidjs/solid) and [Recoiljs](https://github.com/facebookexperimental/Recoil).\n\n## Installation\n\n### NPM\n\n[`npm i simply-reactive`](https://www.npmjs.com/package/simply-reactive)\n\n```ts\nimport { createAtom, createEffect, createSelector } from 'simply-reactive';\n```\n\n### CDN\n\n#### ESM\n\n```html\n\u003cscript type=\"module\"\u003e\n  import {\n    createAtom,\n    createEffect,\n    createSelector,\n  } from 'https://cdn.jsdelivr.net/npm/simply-reactive';\n\u003c/script\u003e\n```\n\n#### UMD\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/simply-reactive/cdn/umd.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  const { createAtom, createEffect, createSelector } = simplyReactive;\n\u003c/script\u003e\n```\n\n## Demos\n\n- Counting with Atoms \u0026 Selectors: [demos/count.ts](./demos/count.ts)\n- Counting with Groups: [demos/groups.ts](./demos/groups.ts)\n- Interactive web page: [demos/web.html](./demos/web.html)\n- Simple web app: https://jsfiddle.net/06xo19v2/39\n- Simple web app with [easy-render](https://github.com/Olian04/easy-render): \u003chttps://jsfiddle.net/20crm4ah/\u003e\n- Simple web app with [brynja](https://github.com/Olian04/brynja): \u003chttps://jsfiddle.net/rb4xc25f/47/\u003e\n\n## Documentation\n\n`Simply-reactive` provides three reactive primitives:\n\n- [Atoms](#atom) are single pieces of reactive state.\n- [Selectors](#selector) are pieces of derived reactive state.\n- [Effects](#effect) are side effects produced by changes to the reactive graph.\n\n`Simply-reactive` also provides four reactive composites:\n\n- [Groups](#group) are atoms containing collections of reactive primitives or other reactive composites.\n- [Effect Groups](#effect-group) are collections of effects used for enabeling and disabeling multiple effects at once.\n- [Resources](#resource) are selectors specifically optimized for data fetching.\n- [External Selectors](#external-selector) are selectors specifiacally optimized for interfacing with other reactive systems.\n\n### Atom\n\nAtoms are single pieces of reactive state.\n\n```ts\nconst Count = createAtom({\n  default: 0,\n});\nCount.set(1);\nconsole.log(`Count: ${Count.get()}`);\n```\n\n### Selector\n\nSelectors are pieces of derived reactive state.\n\n```ts\nconst DoubleCount = createSelector({\n  get: () =\u003e {\n    return Count.get() * 2;\n  },\n});\nconsole.log(`Count: ${DoubleCount.get()}`);\n```\n\n### Effect\n\nEffects are side effects produced by changes to the reactive graph.\n\n```ts\ncreateEffect(() =\u003e {\n  console.log(`${DoubleCount.get()} is twice as big as ${Count.get()}`);\n});\n\nsetInterval(() =\u003e {\n  Count.set((c) =\u003e c + 1);\n}, 1000);\n```\n\n### Group\n\nGroups are atoms containing collections of reactive primitives or other reactive composites.\n\n```ts\nconst CountGroup = createGroup({\n  getDefault: () =\u003e\n    createAtom({\n      default: 0,\n    }),\n});\n\nconst DoubleCountGroup = createGroup({\n  getDefault: (index) =\u003e\n    createSelector({\n      get: () =\u003e CountGroup.find(index).get() * 2,\n    }),\n});\n\nCountGroup.find(0).set(5);\nCountGroup.find(1).set(2);\nconsole.log(DoubleCountGroup.find(0).get()); // 10\nconsole.log(DoubleCountGroup.find(1).get()); // 4\nconsole.log(DoubleCountGroup.find(2).get()); // 0\n```\n\n### Effect Group\n\nEffect Groups are collections of effects used for enabeling and disabeling multiple effects at once.\n\n```ts\ncreateEffectGroup([\n  () =\u003e (document.getElementById('in-a').value = A.get()),\n  () =\u003e (document.getElementById('in-b').value = B.get()),\n  () =\u003e (document.getElementById('out-a').innerText = A.get()),\n  () =\u003e (document.getElementById('out-b').innerText = B.get()),\n  () =\u003e (document.getElementById('out-product').innerText = A.get() * B.get()),\n]);\n\ndocument.getElementById('in-a').addEventListener('change', (ev) =\u003e {\n  A.set(parseInt(ev.target.value, 10));\n});\ndocument.getElementById('in-b').addEventListener('change', (ev) =\u003e {\n  B.set(parseInt(ev.target.value, 10));\n});\n```\n\n### Resource\n\nResources are selectors specifically optimized for data fetching.\n\n```ts\nconst Data = createResource({\n  get: async () =\u003e fetch(...),\n});\n\nconsole.log(`Data after first load ${await Data.get()}`);\n\nData.invalidate();\nconsole.log(`Data after second load ${await Data.get()}`);\n```\n\n### External Selector\n\nExternal Selectors are selectors specifiacally optimized for interfacing with other reactive systems.\n\n```ts\nconst Name = createExternalSelector({\n  default: '',\n  setup: (set) =\u003e {\n    document\n      .querySelector('#input')\n      .addEventListener('change', (ev) =\u003e set(ev.target.value));\n  },\n});\n\ncreateEffect(() =\u003e {\n  document.querySelector('#output').innerText = `Hello, ${\n    Name.get() ?? 'World'\n  }!`;\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folian04%2Fsimply-reactive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Folian04%2Fsimply-reactive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folian04%2Fsimply-reactive/lists"}