{"id":10660,"library":"compressorjs","title":"Compressor.js","description":"Compressor.js is a client-side JavaScript image compression library that leverages the browser's native `HTMLCanvasElement.toBlob()` method for its core functionality. It performs lossy, asynchronous compression, meaning results can vary slightly across different web browsers and privacy settings. Primarily designed for pre-compressing images on the client before upload, it provides a straightforward API for handling `File` or `Blob` objects. The current stable version is 1.3.0, and the project appears actively maintained with a steady cadence of minor updates addressing bug fixes and introducing new options. Its key differentiator is its reliance on native browser APIs, simplifying its footprint but also making its compression effects browser-dependent. It ships with TypeScript types.","status":"active","version":"1.3.0","language":"javascript","source_language":"en","source_url":"https://github.com/fengyuanchen/compressorjs","tags":["javascript","image","compress","compressor","compressor.js","image-compressor","lossy-compression","front-end","typescript"],"install":[{"cmd":"npm install compressorjs","lang":"bash","label":"npm"},{"cmd":"yarn add compressorjs","lang":"bash","label":"yarn"},{"cmd":"pnpm add compressorjs","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Compressor.js uses a default export for its main class in ESM environments.","wrong":"import { Compressor } from 'compressorjs';","symbol":"Compressor","correct":"import Compressor from 'compressorjs';"},{"note":"For CommonJS environments, it's recommended to explicitly import from the 'compressor.common.js' bundle to ensure correct module resolution, as specified by the package.","wrong":"const Compressor = require('compressorjs');","symbol":"Compressor","correct":"const Compressor = require('compressorjs/dist/compressor.common.js');"},{"note":"`setDefaults` is a static method on the `Compressor` class, not a named export. Access it via the default imported `Compressor` instance.","wrong":"import { setDefaults } from 'compressorjs';","symbol":"Compressor.setDefaults","correct":"import Compressor from 'compressorjs'; Compressor.setDefaults({ quality: 0.8 });"}],"quickstart":{"code":"import Compressor from 'compressorjs';\n\n// Create a dummy file input for demonstration purposes\nconst inputElement = document.createElement('input');\ninputElement.setAttribute('type', 'file');\ninputElement.setAttribute('id', 'fileInput');\ninputElement.setAttribute('accept', 'image/*');\ndocument.body.appendChild(inputElement);\n\ndocument.getElementById('fileInput')?.addEventListener('change', (e) => {\n  const target = e.target as HTMLInputElement;\n  const file = target.files?.[0];\n\n  if (!file) {\n    console.log('No file selected.');\n    return;\n  }\n\n  new Compressor(file, {\n    quality: 0.6,\n    maxWidth: 800,\n    maxHeight: 600,\n    // Output the original image instead of the compressed one if the compressed size is larger.\n    strict: true,\n    success(result) {\n      console.log('Compression successful! Compressed file:', result);\n      // The 'result' is a File object (or Blob in older versions).\n      // You can now upload this 'result' to your server.\n      const formData = new FormData();\n      formData.append('compressedImage', result, result.name);\n\n      // Example of what you might do next (e.g., using fetch or axios):\n      // fetch('/path/to/upload', { method: 'POST', body: formData })\n      //   .then(response => console.log('Upload success', response))\n      //   .catch(error => console.error('Upload error', error));\n\n      const reader = new FileReader();\n      reader.onload = (event) => {\n        const img = document.createElement('img');\n        img.src = event.target?.result as string;\n        img.style.maxWidth = '200px';\n        document.body.appendChild(img);\n        console.log('Displaying compressed image preview.');\n      };\n      reader.readAsDataURL(result);\n    },\n    error(err) {\n      console.error('Compression error:', err.message);\n    },\n  });\n});","lang":"typescript","description":"Demonstrates how to select an image file from an input, compress it using Compressor.js with specific quality and dimension constraints, and then preview the compressed image or prepare it for upload."},"warnings":[{"fix":"Always test compression results across your target browsers. For applications requiring consistent compression across all clients or server-side processing, consider implementing server-side image optimization as a fallback or primary method.","message":"Compressor.js relies on the browser's native `HTMLCanvasElement.toBlob()` method, which performs lossy compression. The final image quality and compression efficiency can vary significantly across different web browsers and their implementations.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Structure your code to ensure all operations dependent on the compressed image are executed inside the `success` callback provided to the Compressor constructor.","message":"The compression process is asynchronous, meaning the compressed image `result` is only accessible within the `success` callback function. Attempting to access `result` outside this callback will lead to undefined behavior or errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Inform users about this browser-specific privacy setting's impact. If compression is critical, provide alternative client-side strategies or prompt users to adjust their browser settings.","message":"In Firefox, with `privacy.resistFingerprinting` mode enabled, `canvas.getContext('2d').getImageData()` might be unavailable. In such scenarios, Compressor.js (v1.3.0 and later) will output the original image instead of attempting compression.","severity":"gotcha","affected_versions":">=1.3.0"},{"fix":"Review the `strict` option and its exceptions carefully. If you explicitly need a compressed output even if it's larger, set `strict: false`, but be aware of the potential for increased file sizes.","message":"By default (`strict: true`), the library will output the original image if the compressed image's size is larger than the original, unless specific options like `retainExif`, a `mimeType` change, or explicit `width`/`height` constraints are set.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to version 1.1.1 or later to resolve Node.js loading issues. For legacy Node.js environments, ensure proper Babel or transpilation configuration if you must use older versions of the library.","message":"Prior to version 1.1.1, Compressor.js could encounter loading errors when used in Node.js environments due to incompatible syntax in its bundled files.","severity":"breaking","affected_versions":"<1.1.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure that images loaded from external domains are served with proper CORS headers (e.g., `Access-Control-Allow-Origin: *` or specific domains). For locally generated or user-provided files, this error is less common but can indicate browser security restrictions.","cause":"This error can occur when canvas operations (like `toBlob()`) are attempted on images loaded from different origins without appropriate Cross-Origin Resource Sharing (CORS) headers. While some internal cases were fixed in v1.0.6, it can still manifest with external image sources.","error":"The operation is insecure"},{"fix":"Ensure your JavaScript code executes after the DOM is ready. Place your script tag at the end of the `<body>` or wrap your initialization code in a `DOMContentLoaded` event listener (e.g., `document.addEventListener('DOMContentLoaded', () => { ... });`).","cause":"This error typically indicates that the DOM element for the file input was not found or was accessed before the HTML document was fully loaded.","error":"TypeError: Cannot read properties of undefined (reading 'files')"},{"fix":"Verify that the `file` argument passed to `new Compressor(file, options)` is a valid `File` or `Blob` object, and always instantiate the class with `new Compressor(...)`.","cause":"This error usually occurs if `new Compressor()` is called with an invalid `file` argument (e.g., `null` or `undefined`) or if the `Compressor` class is not correctly instantiated using the `new` keyword.","error":"TypeError: Cannot set properties of undefined (setting 'quality')"}],"ecosystem":"npm"}