Never worry about polyfills again.
This is a web service that returns a minified and encoded bundle of only the polyfills your users need.
It's like polyfill.io, but it has additional polyfills such as Web Components, Pointer Events, and much more.
It is also potentially faster since all unique polyfill combinations are cached in memory and returned immediately as requested.
And, it supports different kinds of encodings for the smallest possible network bandwidth overhead, including Brotli and Gzip.
The web service is hosted and live at https://polyfill.app/api. It is free to use, and there are no quota limits. See the Hosting section for details on how to host it yourself, if you want to.
- Sends only the polyfills your users actually need
- Wide range of polyfills for modern technologies such as Web Components, Pointer Events, Intl (including RelativeTimeFormatandListFormat), and much more.
- Automatic deduplication and insertion of missing dependencies of requested polyfills
- Supports multiple environments, including Browsers, Workers, and even Node.
- Brotli and Gzip compression
- Intelligent disk- and memory caching for maximum speed and availability
- Completely free
Polyfiller is kindly supported by and relies heavily on BrowserStack for cross-browser testing to ensure maximum cross-browser compatibility.
Polyfiller is kindly supported by JetBrains for software development tools:
Become a sponsor/backer and get your logo listed here.
|  | ||||
|---|---|---|---|---|
| Bubbles Twitter: @usebubbles | Xerox | Trent Raymond | scrubtheweb | Joel | 
- Description
- Supporters
- Backers
- Table of Contents
- Install
- Usage
- Examples
- Web Service API Reference
- Contributing
- Maintainers
- FAQ
- Logo
- License
$ npm install @wessberg/polyfiller
$ yarn add @wessberg/polyfiller
$ pnpm add @wessberg/polyfiller
Polyfiller is already hosted at https://polyfill.app/api as a free web service, but you can install it, for example if
you want to host it yourself. See the Hosting section for more details on that.
Polyfiller can be used both in a Browser, Worker, and Node environment. By default, the assumed environment is Browser.
Place a <script> tag inside your index.html file with a src pointing at https://polyfill.app/api/polyfill.
In the following example, polyfills for ES2015 and Shadow DOM are requested:
<!-- An example of requesting polyfills for an ES2015 environment as well as Web Component support
-->
<script crossorigin src="https://polyfill.app/api/polyfill?features=es,web-components"></script>A targeted bundle will be returned that only contains the specific polyfills the browser needs!
When a browser (or robot) visits your site, Polyfiller evaluates the user agent against Caniuse and decides what is supported and what isn't.
It is up to you to decide which polyfills you need, but the web service will automatically make sure to include every dependency of those polyfills, but only if the browser doesn't already support them.
See this or this section for details on how to use Polyfiller from Web Workers/ServiceWorkers and Node.
You can provide options to Polyfiller via query parameters such as minify and sourcemap to adjust the received payload to your liking.
In this example:
- espolyfills those EcmaScript features that the browser doesn't support.
- intersection-observeris polyfilled, even if the browser supports it, because it has the- forceoption.
- intlis polyfilled, with the inclusion of- Intl.ListFormatand- Intl.RelativeTimeFormat, if the browser doesn't support it, and the- enlocale data is included.
- Sourcemaps are generated, and the bundle is minified
<script crossorigin src="https://polyfill.app/api/polyfill?minify&sourcemap&features=es,intersection-observer|force,intl|locale=en"></script>This example shows how you can add support for Web Components:
- templatepolyfills the- HTMLTemplateElementif the browser doesn't support it.
- shadow-dompolyfills the- Shadow DOMv1 specification if the browser doesn't support it.
- custom-elementspolyfills the- Custom Elementsv1 specification if the browser doesn't support it.
<script crossorigin src="https://polyfill.app/api/polyfill?features=template,shadow-dom,custom-elements"></script>For your convenience, the web-components alias requests those three features.
<script crossorigin src="https://polyfill.app/api/polyfill?features=web-components"></script>For your convenience, a few libraries are included that isn't strictly polyfills but are closely related to compatibility: In this example:
- systemjsAdds the- SystemJSES module loader. Useful if you target a browser that doesn't support ES-modules and want to use something like dynamic imports and code-splitting.
- regenerator-runtimeis added, which is what babel transpiles async functions and generator functions into if you don't target browsers that supports it.
<script crossorigin src="https://polyfill.app/api/polyfill?features=systemjs,regenerator-runtime"></script>Retrieves a bundle of polyfills.
Polyfiller will use the incoming Accept-Encoding headers of the request to decide if the response should be Brotli encoded, Gzip encoded or not encoded at all.
| Parameter | Description | 
|---|---|
| features | A comma-separated string of all the features you want to include in your bundle (if required by the browser). Eachfeaturemay receive zero or moreoptions. Someoptions are supported for allfeatures while others only support specificfeatures. | 
| context | Can be either window,worker, ornode. Use this to instructPolyfillerto optimize polyfills for the given environment, as well as to exclude polyfills that doesn't support the given context. | 
| sourcemap | If given, or if it has a value of true,Polyfillerwill be instructed to generate SourceMaps. Use this in development for better stack traces. | 
| minify | If given, Polyfillerwill send back a minified Polyfill bundle. | 
A feature has a name and may receive zero or more options.
For example, intl is a feature name, and so is custom-elements.
See the Feature name section for the full list of possible feature names.
An option is some data associated with a feature.
It is associated with a feature using the | (pipe) operator.
For example, here's how to associate the force option with a feature:
animation|force.
Some options apply to all features while others only apply to specific features. For example:
intl|locale=en
By default, features that are already supported by the browser sending the request to the web service won't be polyfilled. That would be a waste of network bandwidth and parsing cost for your users.
However, sometimes you may want to force a polyfill, even for browsers that support a feature.
In order to do so, associate the force option with a feature. For example:
animation|force
This will force-apply a polyfill for Web Animations.
This option only works with intl, intl.core, intl.list-format, or intl.relative-time-format.
The Intl family of polyfills rely on locale data for them to work. There are over 600 different locale files shipped. Sending all of them back over the network would take way too much bandwidth.
Instead, if you just ask for the intl, intl.core, intl.list-format, or intl.relative-time-format features, they will be returned without any locale data.
To add one or more locales, use the locale option. For example:
intl|locale=en
This will return a bundle of Intl-related polyfills along with locale data for the en (English) language code.
You can ask for as many you want by separating the locales with the ~ operator. For example:
intl|locale=en~da~fr
This will return a bundle of Intl-related polyfills along with locale data for en (English), da (Danish), and fr (French).
SystemJS comes in two base versions, a minimal version called s, and a more feature-complete version called system.
By default, the system variant will be used. You can decide which one to use with the variant option.
For example: systemjs|variant=s selects the s variant, while systemjs|variant=system selects the system variant.
Zone.js, which is supported by Polyfiller, can be configured with some extra options to enhance its operation or support interoperability with more APIs:
| Option | Description | 
|---|---|
| error | Generates more readable Stack traces when using Zone | 
| shadydom | Makes Zone compatible with the ShadyDOM polyfill. | 
| mediaquery | Patches the Media Query API | 
| fetch | Patches the Fetch API. | 
| resizeobserver | Patches the ResizeObserver API. | 
| Option | Description | 
|---|---|
| experimental | You can pass the experimentaloption toshadow-dom(or any of its aliases such asweb-components) to base it on some experimental features that may reduce bugs in older browsers such as IE and Edge <= 15. | 
| lit | If you're going to be using Lit, you can also pass the litoption toshadow-dom(or any of its aliases such asweb-components) to include its polyfill support layer. | 
You can also request polyfills from a Worker. It is highly recommended that you pass in the context query parameter with a value of worker to instruct Polyfiller to optimize polyfills for a Worker environment, as well as to
not include any polyfills that won't work in a Worker environment.
// Provide a context query parameter with a value of 'worker' to avoid polyfills that doesn't support that environment
importScripts("https://polyfill.app/api/polyfill?features=es,intl,web-animations&context=worker");You can also request polyfills from Node, if that's a thing you want to do. It is highly recommended that you pass in the context query parameter with a value of node to instruct Polyfiller to optimize polyfills for a Node environment, as well as to
not include any polyfills that won't work in a Node environment.
(async () => {
	// Remember to provide a user agent header if you want anything meaningful back
	const response = await fetch("https://polyfill.app/api/polyfill?features=intl&context=node");
	const text = await response.text();
	// Apply the polyfills
	new Function(text)();
})();Do you want to contribute? Awesome! Please follow these recommendations.
| Frederik Wessberg Twitter: @FredWessberg Github: @wessberg Lead Developer | 
These two services are very much alike. In fact, Polyfiller depends on the library behind polyfill.io for some of the polyfills!
Polyfiller exists for two reasons:
- A wider range of available polyfills such as Web Components, PointerEvents and Proxies
- Deep integration with Caniuse. If you use something likebabel-preset-envwith abrowserslistand you generate this automatically based on the features you want to support with a tool such as browserslist-generator, both syntax detection for transpiling, and feature detection for polyfilling will be seamlessly based on yourbrowserslist.
Polyfiller is already hosted at https://polyfill.app/api as a free web service, but feel free to host it yourself.
The server is built with support for both HTTP2 and HTTP. The environment variable HTTP2=[true|false] decides whether a HTTP2 server will be hosted or not.
If you use a load balancer and something like nginx in a reverse proxy setup, please know that nginx doesn't support HTTP2 via its proxy module, so you have to use HTTP1.1 there. Thankfully, it is as easy as setting HTTP2=false before launching the server and setting HTTPS=false.
All credits go to Andreas Mehlsen (@andreasbm) for the awesome logo design.
MIT © Frederik Wessberg (@FredWessberg) (Website)
Here's a full list of all possible feature names.
Note that these will be deduplicated. For example, if you request es.object, but also request es, es.object will only be included once as part of es.
And, if you request performance.now, date.now will also be included since the polyfill depends on it. You don't have to worry about dependencies.
Bold-formatted polyfills are aliases for one or several other related features.
- formdata- form-data
 
- requestidlecallback- request-idle-callback
 
- requestanimationframe- request-animation-frame
 
- es- es.promise
- es.object
- es.function
- es.array
- es.array-buffer
- es.string
- es.data-view
- es.regexp
- es.number
- es.math
- es.date
- es.symbol
- es.collections
- es.typed-array
- es.reflect
- es.global-this
 
- es2015- es
 
- es.promise- es.promise.constructor
- es.promise.any
- es.promise.all-settled
- es.promise.finally
 
- es.object- es.object.assign
- es.object.create
- es.object.define-getter
- es.object.define-setter
- es.object.entries
- es.object.from-entries
- es.object.get-own-property-descriptors
- es.object.lookup-getter
- es.object.lookup-setter
- es.object.values
- es.object.define-properties
- es.object.define-property
- es.object.freeze
- es.object.get-own-property-descriptor
- es.object.get-own-property-names
- es.object.get-prototype-of
- es.object.is-extensible
- es.object.is-frozen
- es.object.is-sealed
- es.object.is
- es.object.keys
- es.object.prevent-extensions
- es.object.seal
- es.object.set-prototype-of
- es.object.to-string
 
- es.function- es.function.bind
- es.function.name
 
- es.array- es.array.concat
- es.array.copy-within
- es.array.every
- es.array.flat
- es.array.flat-map
- es.array.fill
- es.array.filter
- es.array.find
- es.array.find-index
- es.array.for-each
- es.array.from
- es.array.includes
- es.array.index-of
- es.array.is-array
- es.array.iterator
- es.array.join
- es.array.last-index-of
- es.array.map
- es.array.of
- es.array.reduce
- es.array.reduce-right
- es.array.slice
- es.array.some
- es.array.sort
- es.array.species
- es.array.splice
- es.array.at
- es.array.find-last
- es.array.find-last-index
 
- es.array-buffer- es.array-buffer.constructor
- es.array-buffer.is-view
- es.array-buffer.slice
 
- es.string- es.string.anchor
- es.string.big
- es.string.blink
- es.string.bold
- es.string.code-point-at
- es.string.ends-with
- es.string.fixed
- es.string.fontcolor
- es.string.fontsize
- es.string.from-code-point
- es.string.includes
- es.string.italics
- es.string.iterator
- es.string.link
- es.string.match
- es.string.pad-end
- es.string.pad-start
- es.string.raw
- es.string.repeat
- es.string.search
- es.string.small
- es.string.split
- es.string.starts-with
- es.string.strike
- es.string.sub
- es.string.sup
- es.string.trim
- es.string.trim-start
- es.string.trim-end
- es.string.replace-all
- es.string.match-all
- es.string.at
 
- es.regexp- es.regexp.constructor
- es.regexp.flags
- es.regexp.to-string
 
- es.number- es.number.constructor
- es.number.epsilon
- es.number.is-finite
- es.number.is-integer
- es.number.is-nan
- es.number.is-safe-integer
- es.number.max-safe-integer
- es.number.min-safe-integer
- es.number.parse-float
- es.number.parse-int
- es.number.to-fixed
- es.number.to-precision
 
- es.math- es.math.acosh
- es.math.asinh
- es.math.atanh
- es.math.cbrt
- es.math.clz32
- es.math.cosh
- es.math.expm1
- es.math.fround
- es.math.hypot
- es.math.imul
- es.math.log1p
- es.math.log2
- es.math.log10
- es.math.sign
- es.math.sinh
- es.math.tanh
- es.math.trunc
 
- es.date- es.date.now
- es.date.to-iso-string
- es.date.to-json
- es.date.to-primitive
- es.date.to-string
 
- es.symbol- es.symbol.async-iterator
- es.symbol.has-instance
- es.symbol.is-concat-spreadable
- es.symbol.iterator
- es.symbol.constructor
- es.symbol.match
- es.symbol.match-all
- es.symbol.replace
- es.symbol.search
- es.symbol.species
- es.symbol.split
- es.symbol.to-primitive
- es.symbol.to-string-tag
- es.symbol.unscopables
- es.symbol.description
 
- es.collections- es.map
- es.weak-map
- es.set
- es.weak-set
 
- es.typed-array- es.typed-array.copy-within
- es.typed-array.every
- es.typed-array.fill
- es.typed-array.filter
- es.typed-array.find
- es.typed-array.find-index
- es.typed-array.float32-array
- es.typed-array.float64-array
- es.typed-array.for-each
- es.typed-array.from
- es.typed-array.includes
- es.typed-array.index-of
- es.typed-array.int8-array
- es.typed-array.int16-array
- es.typed-array.int32-array
- es.typed-array.iterator
- es.typed-array.join
- es.typed-array.last-index-of
- es.typed-array.map
- es.typed-array.of
- es.typed-array.reduce
- es.typed-array.reduce-right
- es.typed-array.reverse
- es.typed-array.set
- es.typed-array.slice
- es.typed-array.some
- es.typed-array.sort
- es.typed-array.subarray
- es.typed-array.to-locale-string
- es.typed-array.to-string
- es.typed-array.uint8-array
- es.typed-array.uint8-clamped-array
- es.typed-array.uint16-array
- es.typed-array.uint32-array
- es.typed-array.at
- es.typed-array.find-last
- es.typed-array.find-last-index
 
- es.reflect- es.reflect.apply
- es.reflect.construct
- es.reflect.define-property
- es.reflect.delete-property
- es.reflect.get
- es.reflect.get-own-property-descriptor
- es.reflect.get-prototype-of
- es.reflect.has
- es.reflect.is-extensible
- es.reflect.own-keys
- es.reflect.prevent-extensions
- es.reflect.set
- es.reflect.set-prototype-of
 
- dom.collections.iterable- dom.collections.iterator
- dom.collections.for-each
 
- intl- intl.date-time-format
- intl.display-names
- intl.get-canonical-locales
- intl.list-format
- intl.locale
- intl.number-format
- intl.plural-rules
- intl.relative-time-format
 
- animation- web-animations
 
- web-components- custom-elements
- shadow-dom
- template
 
- event- event.constructor
- event.focusin
- event.hashchange
 
- setimmediate- set-immediate
 
- globalthis- es.global-this
 
- global-this- es.global-this
 
- adopted-style-sheets- constructable-style-sheets
 
- structuredclone- structured-clone
 
- base64- atob
- btoa
 
- systemjs
- zone
- performance.now
- url
- object-fit
- console
- blob
- proxy
- es.string.replace
- pointer-event
- xhr
- fetch
- regenerator-runtime
- queryselector
- document-fragment
- node.parentelement
- scroll-behavior
- focus-visible
- node.contains
- window
- document
- class-list
- dom-token-list
- element
- custom-event
- event-source
- get-computed-style
- intersection-observer
- mutation-observer
- resize-observer
- broadcast-channel
- proto


