Gathering detailed insights and metrics for @web/polyfills-loader
Gathering detailed insights and metrics for @web/polyfills-loader
Gathering detailed insights and metrics for @web/polyfills-loader
Gathering detailed insights and metrics for @web/polyfills-loader
@web/rollup-plugin-polyfills-loader
Plugin for injecting a polyfills loader to HTML pages
@open-wc/polyfills-loader
Load web component polyfills using dynamic imports
byu-web-component-loader-generator
Generates a bootstrap file that ensures that the proper Web Component polyfills are loaded
Guides, tools and libraries for modern web development.
npm install @web/polyfills-loader
Typescript
Module System
Min. Node Version
Node Version
NPM Version
@web/test-runner-playwright@0.11.1
Updated on Jun 11, 2025
@web/rollup-plugin-import-meta-assets@2.3.0
Updated on Jun 10, 2025
@web/test-runner@0.20.2
Updated on May 21, 2025
@web/storybook-utils@1.1.2
Updated on May 19, 2025
@web/mocks@1.3.2
Updated on May 14, 2025
@web/storybook-framework-web-components@0.2.1
Updated on May 13, 2025
TypeScript (56.55%)
JavaScript (41.08%)
HTML (2.32%)
MDX (0.04%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
2,324 Stars
3,124 Commits
309 Forks
23 Watchers
58 Branches
150 Contributors
Updated on Jul 15, 2025
Latest Version
2.3.1
Package Id
@web/polyfills-loader@2.3.1
Unpacked Size
86.53 kB
Size
22.16 kB
File Count
34
NPM Version
10.8.2
Node Version
20.18.3
Published on
Feb 27, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
19
3
The polyfills loader makes it easy to manage loading polyfills and/or serving different versions of your application based on browser support. It generates a script that loads the necessary polyfills and the appropriate version of the application through on runtime feature detection.
A simplified version of the loader:
1// detect support for various browser features, load a polyfill if necessary 2var polyfills = []; 3if (!('fetch' in window)) { 4 polyfills.push(loadScript('./polyfills/fetch.js')); 5} 6 7if (!('IntersectionObserver' in window)) { 8 polyfills.push(loadScript('./polyfills/intersection-observer.js')); 9} 10 11// wait for polyfills to load 12Promise.all(polyfills).then(function () { 13 if (!('noModule' in HTMLScriptElement.prototype)) { 14 // browser doesn't support es modules, load a SystemJS build with es5 15 System.import('./legacy/app.js'); 16 } else { 17 // browser supports modules, import a modern build 18 import('./app.js'); 19 } 20});
The primary reason for this project is to make it easier to build performant web apps. The web ecosystem is evolving fast, it's easy to end up with many unnecessary polyfills in your application because all supported browsers already implement the feature you are using.
By loading polyfills conditionally, you make sure you only load what's necessary and you don't need to include them in your main bundle. Polyfills are hashed based on content, so they can be cached indefinitely by a web server or service worker.
Serving different versions of your application means you don't need to serve the lowest common denominator to all of your users. This is often achieved used <script type="module">
and <script nomodule>
. The polyfills loader uses a variation of this, where the feature detection happens in javascript because we need to ensure polyfills are loaded before any of your application code is run.
Browser optimize loading webpages by scanning ahead for script tags and fetching them right away. Because the polyfills loader moves the loading of scripts into javascript, we lose out on this optimization. For the polyfills, this is intentional, because we don't want to load them all the time and since they will be cached this optimization does not do much anyway.
For your application code, we recommend using preload
(or modulepreload
when it is widely supported) links to ensure your application's modern build is fetched from the start.
1<head> 2 <link rel="preload" href="./app.js" /> 3 <!-- for module scripts, add a corrs attribute --> 4 <link rel="preload" href="./app.js" crossorigin="anonymous" /> 5</head>
You will most likely use the polyfills loader as part of another tool, but it can be used directly as well.
A typical web app which loads as modules on modern browsers, and system js on older browsers:
1const config = { 2 modern: { 3 files: [{ type: 'module', path: 'app.js' }], 4 }, 5 legacy: [ 6 { 7 test: "!('noModule' in HTMLScriptElement.prototype)", 8 files: [{ type: 'systemjs', path: 'app.js' }], 9 }, 10 ], 11 polyfills: { 12 hash: true, 13 coreJs: true, 14 fetch: true, 15 abortController: true, 16 regeneratorRuntime: true, 17 dynamicImport: true, 18 webcomponents: true, 19 intersectionObserver: true, 20 constructibleStylesheets: true, 21 URLPattern: true, 22 resizeObserver: true, 23 scopedCustomElementRegistry: true, 24 }, 25 minify: true, 26};
The files to load on modern browsers. Loaded if no legacy entry points match for the current browser, or if none are configured. Each file specifies how it should be loaded.
1const config = { 2 modern: { 3 files: [ 4 // filetype can be: 'module', 'script' or 'systemjs 5 { type: 'script', path: 'file-a.js' }, 6 { type: 'module', path: 'file-b.js' }, 7 ], 8 }, 9};
Sets of files to load on legacy browsers, and the runtime feature detection to execute to determine whether it should be loaded.
1const config = { 2 legacy: [ 3 { 4 test: "!('noModule' in HTMLScriptElement.prototype)", 5 files: [ 6 // filetype can be: 'module', 'module-shim', 'script' or 'systemjs 7 { type: 'systemjs', path: 'file-a.js' }, 8 { type: 'systemjs', path: 'file-b.js' }, 9 ], 10 }, 11 { 12 test: "!('foo' in window)", 13 files: [ 14 // filetype can be: 'module', 'script' or 'systemjs 15 { type: 'script', path: 'file-a.js' }, 16 { type: 'script', path: 'file-b.js' }, 17 ], 18 }, 19 ], 20};
The polyfills config controls which polyills are injected onto the page. These are the possible polyfills:
They can be turned on using booleans. When using the polyfills loader directly, these are default false. Other tools may turn on different defaults.
1const config = { 2 polyfills: { 3 coreJs: true, 4 fetch: true, 5 webcomponents: true, 6 }, 7};
In order to define css variables outside of a web component in IE11, you need to wrap the <style>
tag inside of a <shady-css-scoped>
tag. This tag is provided by the shady-css-scoped-element package, and will be included if you use both the webcomponents and shadyCssCustomStyle polyfills.
index.html
1<shady-css-scoped> 2 <style> 3 html { 4 --my-button-color: pink; 5 } 6 </style> 7</shady-css-scoped>
config.js
1const config = { 2 polyfills: { 3 webcomponents: true, 4 shadyCssCustomStyle: true, 5 }, 6};
With the hash
option, polyfill filenames can be hashed based on their content, this allows them to be cached indefinitely.
1const config = { 2 polyfills: { 3 hash: true, 4 coreJs: true, 5 fetch: true, 6 webcomponents: true, 7 }, 8};
If you need a polyfill that isn't available in the default list, you can add a custom polyfill. These consist of at least a unique name, a path where to find the polyfill and a bit of javascript executed at runtime to test whether the polyfill should be loaded.
1const config = { 2 polyfills: { 3 hash: true, 4 fetch: true, 5 custom: [ 6 { 7 // the name, must be unique 8 name: 'my-feature-polyfill', 9 // path to the polyfill fle 10 path: require.resolve('my-feature-polyfill'), 11 // a test that determines when this polyfill should be loaded 12 // often this is done by checking whether some property of a 13 // feature exists in the window 14 test: "!('myFeature' in window)", 15 16 // optional advanced features: 17 18 // if your polyfill is not yet minified, it can be minified by 19 // the polyfills loaded if you set it to true 20 minify: true, 21 // whether your polyfill should be loaded as an es module 22 module: false, 23 // some polyfills need to be explicitly initialized 24 // this can be done with the initializer 25 initializer: 'window.myFeaturePolyfills.initialize()', 26 }, 27 ], 28 }, 29};
The polyfills loader delays loading any scripts until polyfills are loaded. This can create problems when you rely on specific loading behavior. You can exclude certain scripts with the exclude
option.
1const config = { 2 exclude: { 3 jsScripts: true, 4 jsModules: true, 5 inlineJsScripts: true, 6 inlineJsModules: true, 7 }, 8};
Which directory to load polyfills from. By default, this is ./polyfills
1const config = { 2 polyfillsDir: './generated-files', 3};
Whether the code output should be minified.
1const config = { 2 minify: true, 3};
The createPolyfillsLoader
function takes configuration and returns the javascript code for the polyfills loader. It also returns information about the generated polyfill files, these will need to be made available at runtime so that they can be imported by the loader code.
1const { createPolyfillsLoader } = require('polyfills-loader'); 2 3const result = createPolyfillsLoader({ 4 // see configuration above 5}); 6 7console.log(result.code); 8console.log(result.polyfillFiles);
The injectPolyfillsLoader
function injects a polyfills loader into an existing HTML page. It also injects polyfills for any import maps it finds.
1const { injectPolyfillsLoader } = require('polyfills-loader'); 2 3const html = ` 4<html> 5 <head></head> 6 <body></body> 7</html> 8`; 9 10const result = injectPolyfillsLoader(html, { 11 // see configuration above 12}); 13 14console.log(result.htmlString); 15console.log(result.polyfillFiles);
No vulnerabilities found.
Reason
30 commit(s) and 8 issue activity found in the last 90 days -- score normalized to 10
Reason
no dangerous workflow patterns detected
Reason
license file detected
Details
Reason
no binaries found in the repo
Reason
dependency not pinned by hash detected -- score normalized to 4
Details
Reason
Found 2/8 approved changesets -- score normalized to 2
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
security policy file not detected
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
project is not fuzzed
Details
Reason
25 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More