{"id":15117418,"url":"https://github.com/chrisguttandin/worker-timers","last_synced_at":"2026-02-05T00:14:33.357Z","repository":{"id":21473645,"uuid":"24792198","full_name":"chrisguttandin/worker-timers","owner":"chrisguttandin","description":"A replacement for setInterval() and setTimeout() which works in unfocused windows.","archived":false,"fork":false,"pushed_at":"2025-12-15T15:42:43.000Z","size":25567,"stargazers_count":641,"open_issues_count":7,"forks_count":26,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-12-17T16:06:53.210Z","etag":null,"topics":["clearinterval","cleartimeout","interval","setinterval","settimeout","web-workers","window-timers"],"latest_commit_sha":null,"homepage":"","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/chrisguttandin.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2014-10-04T14:40:48.000Z","updated_at":"2025-12-15T15:42:47.000Z","dependencies_parsed_at":"2025-11-27T12:06:15.062Z","dependency_job_id":null,"html_url":"https://github.com/chrisguttandin/worker-timers","commit_stats":{"total_commits":4248,"total_committers":4,"mean_commits":1062.0,"dds":"0.039548022598870025","last_synced_commit":"c66586d5ee68eb55d3806a22eed5d29746c93f62"},"previous_names":[],"tags_count":259,"template":false,"template_full_name":null,"purl":"pkg:github/chrisguttandin/worker-timers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisguttandin%2Fworker-timers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisguttandin%2Fworker-timers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisguttandin%2Fworker-timers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisguttandin%2Fworker-timers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisguttandin","download_url":"https://codeload.github.com/chrisguttandin/worker-timers/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisguttandin%2Fworker-timers/sbom","scorecard":{"id":159178,"data":{"date":"2025-08-11","repo":{"name":"github.com/chrisguttandin/worker-timers","commit":"eda1ac555b507257961ed665979d6e3a2961aa6c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":2,"reason":"dependency not pinned by hash detected -- score normalized to 2","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/chrisguttandin/worker-timers/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/chrisguttandin/worker-timers/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/chrisguttandin/worker-timers/test.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":0,"reason":"10 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-c75v-2vq8-878f","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-44c6-4v22-4mhx","Warn: Project is vulnerable to: GHSA-4x5v-gmq8-25ch","Warn: Project is vulnerable to: GHSA-8cj5-5rvv-wf4v","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-16T12:51:48.458Z","repository_id":21473645,"created_at":"2025-08-16T12:51:48.458Z","updated_at":"2025-08-16T12:51:48.458Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29102339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-04T22:44:52.815Z","status":"ssl_error","status_checked_at":"2026-02-04T22:44:16.428Z","response_time":62,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["clearinterval","cleartimeout","interval","setinterval","settimeout","web-workers","window-timers"],"created_at":"2024-09-26T01:45:57.084Z","updated_at":"2026-02-05T00:14:33.334Z","avatar_url":"https://github.com/chrisguttandin.png","language":"JavaScript","funding_links":["https://tidelift.com/security"],"categories":["JavaScript"],"sub_categories":[],"readme":"![logo](https://repository-images.githubusercontent.com/24792198/dd93c980-323f-11ea-8a14-a0299de4847a)\n\n# worker-timers\n\n**A replacement for setInterval() and setTimeout() which works in unfocused windows.**\n\n[![version](https://img.shields.io/npm/v/worker-timers.svg?style=flat-square)](https://www.npmjs.com/package/worker-timers)\n\n## Motivation\n\nFor scripts that rely on [WindowTimers](http://www.w3.org/TR/html5/webappapis.html#timers) like `setInterval()` or `setTimeout()` things get confusing when the site which the script is running on loses focus. Chrome, Firefox and maybe others throttle the frequency at which they invoke those timers to a maximum of once per second in such a situation. However this is only true for the main thread and does not affect the behavior of [Web Workers](http://www.w3.org/TR/workers/). Therefore it is possible to avoid the throttling by using a worker to do the actual scheduling. This is exactly what `worker-timers` does.\n\n## Getting Started\n\n`worker-timers` is available as a package on [npm](https://www.npmjs.org/package/worker-timers). Run the following command to install it:\n\n```shell\nnpm install worker-timers\n```\n\nYou can then import the exported functions in your code like this:\n\n```js\nimport { clearInterval, clearTimeout, setInterval, setTimeout } from 'worker-timers';\n```\n\nThe usage is exactly the same (despite of the [error handling](#error-handling) and the\n[differentiation between intervals and timeouts](#differentiation-between-intervals-and-timeouts))\nas with the corresponding functions on the global scope.\n\n```js\nconst intervalId = setInterval(() =\u003e {\n    // do something many times\n}, 100);\n\nclearInterval(intervalId);\n\nconst timeoutId = setTimeout(() =\u003e {\n    // do something once\n}, 100);\n\nclearTimeout(timeoutId);\n```\n\n## Differentiation between Intervals and Timeouts\n\nThe native WindowTimers only maintain a single list of timers. But `worker-timers` maintains two separate lists to store the ids of intervals and timeouts internally. WindowTimers allows intervals to be cancelled by calling `clearTimeout()` and the other way round because it stores all timers in a single list. This is not possible with `worker-timers`.\n\n```js\nconst periodicWork = () =\u003e {};\n\n// This will stop the interval.\nconst windowId = window.setInterval(periodicWork, 100);\nwindow.clearTimeout(windowId);\n\n// This will not cancel the interval. It may cancel a timeout.\nconst workerId = setInterval(periodicWork, 100);\nclearTimeout(workerId);\n```\n\n## Server-Side Rendering\n\nThis package is intended to be used in the browser and requires the browser to have [support for Web Workers](https://caniuse.com/#feat=webworkers). It does not contain any fallback which would allow it to run in another environment like Node.js which doesn't know about Web Workers. This is to prevent this package from silently failing in an unsupported browser. But it also means that it needs to be replaced when used in a web project which also supports server-side rendering. The replacement should be straightforward, at least in theory, because each function has the exact same signature as its corresponding builtin function. But the configuration of a real-life project can be tricky. For a concrete example, please have a look at the [worker-timers-ssr-example](https://github.com/newyork-anthonyng/worker-timers-ssr-example) provided by [@newyork-anthonyng](https://github.com/newyork-anthonyng). It shows the usage inside of a server-side rendered React app.\n\n## Angular (\u0026 Zone.js)\n\nIf `worker-timers` is used inside of an Angular app and Zone.js (which is the default) is used to detect changes, the behavior of `worker-timers` can be confusing. Angular is using Zone.js which is patching the native `setInterval()` and `setTimeout()` functions to get notified about the invocation of their callback functions. But Angular (more specifically Zone.js) is not aware of `worker-timers` and doesn't get notified about any callback invocations. Therefore Angular needs to be notified manually about state changes that occur inside of a callback function which was scheduled with the help of `worker-timers`.\n\n## Security contact information\n\nTo report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisguttandin%2Fworker-timers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisguttandin%2Fworker-timers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisguttandin%2Fworker-timers/lists"}