core-js/stable vs core-js/actual for shared library polyfills
0 reputation · 06 Oct 2021, 16:10 UTC
Polyfill Delivery in Shared Libraries
When developing a shared library intended for diverse environments, there is a tension between providing necessary polyfills and avoiding side effects in the host application. Core-js provides two primary documented paths for this: core-js/stable, which patches global objects, and core-js/actual, which provides polyfills as module bindings without mutating the global namespace.
Global Mutation Trade-offs
Using core-js/stable ensures that all scripts on the page, including third-party dependencies, have access to the patched built-ins. However, this mutates globalThis, which may violate the constraints of a side-effect-free library. Conversely, core-js/actual keeps the library isolated and tree-shakeable, but it provides no coverage for other scripts in the bundle graph that may assume these globals exist.
Since core-js resolves to native implementations when they are correct, mixing these namespaces does not create duplicate identities on modern engines. However, on legacy engines, the boundary between global and explicit polyfills remains a manual architectural decision with no tooling to enforce consistency across a dependency graph.
- Should a shared library prioritize global stability by using
core-js/actualand delegating global patching to the host application? - How can a library ensure its own internal dependencies are polyfilled without risking global namespace pollution in the consumer's environment?