What stays compatible
require('easy-stack')still returns the constructor.- The paths
easy-stack/stack.jsandeasy-stack/es5.jsremain exported. - Tasks still execute synchronously, newest first, with the stack bound as
this. - Tasks still call
this.next()when lower work should continue. autoRun,stop,clear(), and the live contents array remain available.
The v2.1 runtime boundary
Version 2.1 requires Node 22.13 or newer. Native ESM and CommonJS now load the same synchronous stack.js file, and require('easy-stack') still returns the constructor directly without Node's default experimental warning. Node's require(esm) history records that exact boundary.
Remain on easy-stack 2.0.0. The separate stack.cjs implementation is no longer shipped in 2.1.
What changes deliberately
| v1 behavior | v2 contract |
|---|---|
| Package root was CommonJS only. | Conditional exports provide native ESM and CommonJS. |
| Node support claimed Node 6. | The current v2.1 runtime begins at exact Node 22.13. |
add() returned undefined. | add() returns the stack for chaining. |
| Invalid callbacks failed only when invoked. | The entire batch is validated atomically before mutation. |
A thrown task left running stuck true. | The same error is rethrown after the runner returns to idle. |
Root contents() and ES5 contents disagreed. | Every entry uses contents(); the live array is also stack.stack. |
require('easy-stack/es5.js') returned an empty object. | The export map routes CommonJS consumers to a working constructor. |
Update imports and contents access
// CommonJS remains valid
const Stack = require('easy-stack');
// Native ESM is now available
import Stack from 'easy-stack';
// Read or replace the live array
stack.contents();
stack.contents([first, second]);
stack.stack = [first, second];If v1 browser code treated stack.contents as an array property, change it to stack.stack or call stack.contents().
Preserve browser package resolution
easy-stack works with bundlers and without a bundler. Bundlers resolve the bare package import normally; native browser ESM uses an import map before every module script, with no build or transpilation step. Map paths are relative to the HTML document, must be served over HTTP(S), and require the server to expose their targets; file:// is unsupported.
Version 2.1.1 has zero runtime dependencies, so no dependency entries or scoped nested-dependency map are required. Copy the complete normal npm-layout map from the browser guide.
Upgrade checklist
- Confirm production Node is 22.13 or newer; otherwise pin 2.0.0.
- Keep CommonJS imports or adopt the new native ESM import.
- Search browser code for property-style
.contentsaccess. - Ensure every value passed to
add()is a function. - Check code that depended on
add()returningundefined. - Remove direct assignments to
stack.running; it is now read-only. - Run the application's failure paths; a thrown task is now recoverable.
- Use
es5.jsfor browser targets that cannot parse private class fields. - Exercise browser pages through HTTP(S), not
file://, and keep native import maps before every module script.