EyeDropper API Polyfill
The `eyedropper-polyfill` package provides a robust polyfill for the W3C EyeDropper API, enabling developers to integrate a native-like color picking experience into web applications even in browsers that lack native support. Currently at stable version `1.1.5`, the library maintains a steady release cadence, primarily focusing on bug fixes and performance improvements as seen in recent patch releases in January 2026. Its key differentiator is its ability to replicate the EyeDropper functionality by leveraging `html2canvas-pro` internally, which allows it to capture colors from rendered web page content. This makes it a critical tool for ensuring consistent UX across a wider range of browsers, bridging compatibility gaps where the native API is not available, such as older browser versions or specific environments. It's designed for browser-side use and ships with TypeScript definitions for enhanced developer experience.
Common errors
-
ReferenceError: EyeDropper is not defined
cause The `eyedropper-polyfill` package was not imported, or its side-effect import did not execute before `window.EyeDropper` was accessed.fixEnsure `import 'eyedropper-polyfill';` is present and runs early in your application's lifecycle, typically in your main entry file (e.g., `index.ts` or `main.js`). -
TypeError: Cannot read properties of undefined (reading 'open') at new EyeDropper
cause Attempting to instantiate `EyeDropper` directly (e.g., `new EyeDropper()`) instead of accessing it via the `window` object, or `window.EyeDropper` is truly undefined.fixAlways instantiate the EyeDropper using `new window.EyeDropper()`. Verify the polyfill has been imported correctly if `window.EyeDropper` remains undefined. -
DOMException: The user aborted a request.
cause The `open()` method of `EyeDropper` was called with an `AbortSignal`, and `abortController.abort()` was subsequently invoked (either programmatically or by user action if supported by native API).fixThis is expected behavior for abortion. Handle this error case in your `catch` block by checking `error.name === 'AbortError'` to differentiate from other potential errors.
Warnings
- gotcha The `eyedropper-polyfill` package relies on a global side effect to make `window.EyeDropper` available. If the import statement is executed in a script that runs after other scripts attempt to use `EyeDropper`, or if it's placed in a module that is not eagerly evaluated, `window.EyeDropper` may appear undefined.
- gotcha As the polyfill is based on `html2canvas-pro`, it inherits its limitations, particularly regarding cross-origin content. You may not be able to pick colors from elements within iframes from different domains or images loaded from distinct origins due to browser security policies.
- gotcha For TypeScript projects, simply installing the package does not automatically provide global type declarations for `window.EyeDropper`. The TypeScript compiler will report that `EyeDropper` is not found on `window`.
Install
-
npm install eyedropper-polyfill -
yarn add eyedropper-polyfill -
pnpm add eyedropper-polyfill
Imports
- Side-effect import
import { EyeDropperPolyfill } from 'eyedropper-polyfill';import 'eyedropper-polyfill';
- Window.EyeDropper
const eyedropper = new EyeDropper();
const eyedropper = new window.EyeDropper();
- TypeScript types
// tsconfig.json { "compilerOptions": { "types": ["eyedropper-polyfill"] } }
Quickstart
import 'eyedropper-polyfill';
const openEyeDropper = async () => {
if (!window.EyeDropper) {
console.error('EyeDropper API or polyfill not available.');
alert('Your browser does not support the EyeDropper API.');
return;
}
const eyeDropper = new window.EyeDropper();
const abortController = new window.AbortController();
const signal = abortController.signal;
// Optionally abort after 10 seconds
const timeoutId = setTimeout(() => {
console.log('EyeDropper operation timed out, aborting.');
abortController.abort();
}, 10000);
try {
const colorSelectionResult = await eyeDropper.open({ signal });
clearTimeout(timeoutId);
console.log('Selected color:', colorSelectionResult.sRGBHex);
document.body.style.backgroundColor = colorSelectionResult.sRGBHex;
alert(`Selected color: ${colorSelectionResult.sRGBHex}`);
} catch (error) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
console.log('EyeDropper operation was aborted.');
} else {
console.error('Error opening EyeDropper:', error);
}
}
};
// Attach to a button click or call directly
// Example: create a button and call this function
const button = document.createElement('button');
button.textContent = 'Pick a color';
button.style.padding = '10px 20px';
button.style.fontSize = '18px';
button.style.margin = '20px';
button.onclick = openEyeDropper;
document.body.appendChild(button);