Version 1.0.0
@stackline/setimmediate
A shim for the setImmediate efficient script yielding API
Independent maintenance of setimmediate 1.0.5. Original authors and licenses are retained.
Installation
# Preserve existing imports with an npm alias
npm install setimmediate@npm:@stackline/setimmediate@1.0.0
# Or use the scoped package name in your imports
npm install @stackline/setimmediate@1.0.0Node.js: See compatibility notes. Read the compatibility and maintenance notes before migrating.
Usage and API
The reference below may retain upstream package names. Use the alias installation above to run those imports with this Stackline release.
@stackline/setimmediate
Independent maintenance fork of setimmediate@1.0.5. Original API, module format, runtime dependency ranges, and supported Node.js engines are preserved.
npm install @stackline/setimmediate
# Preserve existing imports with an npm alias:
npm install setimmediate@npm:@stackline/setimmediate@1.0.0
See UPSTREAM.md for the exact source and issue review, and CHANGELOG.md for focused maintenance changes. Development and release tooling runs on Node.js 24; that does not change the library runtime requirement.
Maintained by Stackline. Issues · npm.
Upstream documentation
setImmediate.js
A YuzuJS production
Introduction
setImmediate.js is a highly cross-browser implementation of the setImmediate and clearImmediate APIs, proposed by Microsoft to the Web Performance Working Group. setImmediate allows scripts to yield to the browser, executing a given operation asynchronously, in a manner that is typically more efficient and consumes less power than the usual setTimeout(..., 0) pattern.
setImmediate.js runs at “full speed” in the following browsers and environments, using various clever tricks:
- Internet Explorer 6+
- Firefox 3+
- WebKit
- Opera 9.5+
- Node.js
- Web workers in browsers that support
MessageChannel, which I can't find solid info on.
In all other browsers we fall back to using setTimeout, so it's always safe to use.
Macrotasks and Microtasks
The setImmediate API, as specified, gives you access to the environment's task queue, sometimes known as its "macrotask" queue. This is crucially different from the microtask queue used by web features such as MutationObserver, language features such as promises and Object.observe, and Node.js features such as process.nextTick. Each go-around of the macrotask queue yields back to the event loop once all queued tasks have been processed, even if the macrotask itself queued more macrotasks. Whereas, the microtask queue will continue executing any queued microtasks until it is exhausted.
In practice, what this means is that if you call setImmediate inside of another task queued with setImmediate, you will yield back to the event loop and any I/O or rendering tasks that need to take place between those calls, instead of executing the queued task as soon as possible.
If you are looking specifically to yield as part of a render loop, consider using requestAnimationFrame; if you are looking solely for the control-flow ordering effects, use a microtask solution such as asap.
The Tricks
process.nextTick
In Node.js versions below 0.9, setImmediate is not available, but process.nextTick is—and in those versions, process.nextTick uses macrotask semantics. So, we use it to shim support for a global setImmediate.
In Node.js 0.9 and above, process.nextTick moved to microtask semantics, but setImmediate was introduced with macrotask semantics, so there's no need to polyfill anything.
Note that we check for actual Node.js environments, not emulated ones like those produced by browserify or similar. Such emulated environments often already include a process.nextTick shim that's not as browser-compatible as setImmediate.js.
postMessage
In Firefox 3+, Internet Explorer 9+, all modern WebKit browsers, and Opera 9.5+, postMessage is available and provides a good way to queue tasks on the event loop. It's quite the abuse, using a cross-document messaging protocol within the same document simply to get access to the event loop task queue, but until there are native implementations, this is the best option.
Note that Internet Explorer 8 includes a synchronous version of postMessage. We detect this, or any other such synchronous implementation, and fall back to another trick.
MessageChannel
Unfortunately, postMessage has completely different semantics inside web workers, and so cannot be used there. So we turn to MessageChannel, which has worse browser support, but does work inside a web worker.
<script> onreadystatechange
For our last trick, we pull something out to make things fast in Internet Explorer versions 6 through 8: namely, creating a <script> element and firing our calls in its onreadystatechange event. This does execute in a future turn of the event loop, and is also faster than setTimeout(…, 0), so hey, why not?
Usage
In the browser, include it with a <script> tag; pretty simple.
In Node.js, do
npm install --save setimmediate
then
require("setimmediate"); // (somewhere early in your app; it attaches to the global scope.)
Demo
Reference and Reading
Upstream issues and maintenance review
Upstream and compatibility
Independent fork of setimmediate@1.0.5 from
YuzuJS/setImmediate, npm gitHead
f1ccbfdf09cb93aadf77c4aa749ea554503b9234.
The native fork retains history, branches, tags, upstream authors and MIT license.
The shim implementation, side effects, argument passing and cancellation API are unchanged; no runtime dependencies or engine declaration were added.
Issue review — 2026-09-29
- #86: reviewed the wildcard postMessage concern. The implementation posts an internal task identifier, not callback arguments, and checks the message source and prefix. This release preserves the scheduling fallback rather than changing origin behavior without cross-browser evidence. Real Chromium and isolated-VM checks exercise scheduling and cancellation; no broader security guarantee is claimed.
- #84: reported garbage-collection behavior is browser/runtime dependent. This release makes no performance claim or speculative timer rewrite.
- #80: Deno lifecycle behavior remains unverified; no new Deno support claim is added. Node and Chromium contracts are tested separately.
The original tests run with a maintained Mocha version. Additional tests force the shim into an isolated VM, exercise the installed npm tarball, and launch real Chromium. Obsolete Zuul/http-server development runners are replaced by this explicit browser check.
Release changes
Changelog
1.0.0 — 2026-09-29
- Publish the preserved setimmediate 1.0.5 implementation under
@stackline/setimmediate. - Retain the original API, license, contributors and runtime requirements.
- Replace obsolete development runners with maintained Mocha and Puppeteer Core; retain upstream behavior tests and add isolated-VM, installed-tarball and real-Chromium checks.
- Add source attribution, issue review, CI/CodeQL and exact-artifact provenance/release verification.
Release files and references
Package bytes, npm provenance and the immutable GitHub release were verified for this version. Security checks describe the reviewed release; documented compatibility risks and upstream reports are not blanket claims of resolution.