{"id":17598118,"url":"https://github.com/potch/signals","last_synced_at":"2025-04-30T06:08:00.001Z","repository":{"id":175767966,"uuid":"622362201","full_name":"potch/signals","owner":"potch","description":"a small reactive signals library","archived":false,"fork":false,"pushed_at":"2023-06-19T04:19:24.000Z","size":16,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-30T06:07:55.437Z","etag":null,"topics":["reactive-programming","signals"],"latest_commit_sha":null,"homepage":"https://signals-demo.glitch.me/","language":"JavaScript","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/potch.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":"2023-04-01T22:06:11.000Z","updated_at":"2023-06-23T15:45:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"5714ad08-a206-44f9-8b56-1dbcec521889","html_url":"https://github.com/potch/signals","commit_stats":null,"previous_names":["potch/signals"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/potch%2Fsignals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/potch%2Fsignals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/potch%2Fsignals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/potch%2Fsignals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/potch","download_url":"https://codeload.github.com/potch/signals/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251651233,"owners_count":21621716,"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":["reactive-programming","signals"],"created_at":"2024-10-22T09:44:33.068Z","updated_at":"2025-04-30T06:07:59.985Z","avatar_url":"https://github.com/potch.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# signals\n\nA tiny standalone implementation of reactive signals.\n\n## Installation\n\n```\nnpm install @potch/signals\n```\n\n## Demo\n\n[view the demo live on Glitch!](https://signals-demo.glitch.me/)\n\nor to run it locally:\n\n```\nnpm start\n```\n\nthen visit `localhost:8080` in your browser.\n\n## Usage\n\n```js\n// `node example.js`\nimport { signal, computed, effect, batch, onchange } from \"./index.js\";\n\n// signals can be any value\nconst a = signal(2);\nconst b = signal(3);\n\n// computed values are based on signals\nconst c = computed(() =\u003e Math.sqrt(a.value * a.value + b.value * b.value));\n\n// don't trigger dependent effects if the new value is the same\nconst perimeter = onchange(computed(() =\u003e a.value + b.value + c.value));\n\n// effects are for having other code react to changes in signals or computed values\neffect(() =\u003e\n  console.log(`the perimeter of the triangle is ${perimeter.value}`)\n);\n\n// effects and computed values are recomputed whenever their dependencies change\n// in this case the new perimeter will be logged twice\nconsole.log(\"updating sides without `batch`\");\na.value = 4;\nb.value = 5;\n\n// use `batch` to update multiple signals and prevent multiple effect updates\n// this time the new perimeter will only be logged once, after the batch is complete\nconsole.log(\"updating sides with `batch`\");\nbatch(() =\u003e {\n  a.value = 5;\n  b.value = 7;\n});\n```\n\n## How it Works\n\nI built this library to understand how basic reactive \"signals\" work. It's useful for small projects but there are more comprehensive first-party signals implementations available for frameworks and better reactive programming tools out there in general.\n\nWhen a computed value or an effect is created, we mark it as the current context. When the initial value of the context is computed (by running the supplied function), the library detects every access to a signal or computed values `.value` property (via their `get value()` getters) and records a dependency. When the `.value` of signals is set, their dependencies are looked up in a `Map` and the `.update()` method is called. In the case of a computed value, this will update the computed value and propagate updates to _its_ dependencies. In the case of an effect, the effect function is triggered.\n\nThis may not be how other signals implementations work! I wanted to build this without reading anyone else's source first.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpotch%2Fsignals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpotch%2Fsignals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpotch%2Fsignals/lists"}