{"id":10689,"library":"cropperjs","title":"Cropper.js - JavaScript Image Cropper","description":"Cropper.js is a powerful, pure JavaScript library for image cropping that provides extensive functionalities including moving, zooming, rotating, and scaling images directly within web browsers. The current stable version is 2.1.1, with the project demonstrating active maintenance through consistent patch and minor releases, indicating ongoing development and bug fixes. A key differentiator is its standalone nature, operating without external dependencies like jQuery, making it lightweight and suitable for modern JavaScript ecosystems. It offers a highly configurable and extensible API, allowing developers to tailor the cropping experience precisely. The library ships with comprehensive TypeScript declaration files, ensuring excellent developer experience in TypeScript projects, and supports both UMD and ESM module formats for broad compatibility across different environments.","status":"active","version":"2.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/fengyuanchen/cropperjs","tags":["javascript","image","crop","move","zoom","rotate","scale","cropper","cropper.js","typescript"],"install":[{"cmd":"npm install cropperjs","lang":"bash","label":"npm"},{"cmd":"yarn add cropperjs","lang":"bash","label":"yarn"},{"cmd":"pnpm add cropperjs","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Cropper.js v2+ primarily exports a default. For CommonJS, `require('cropperjs').default` is typically needed.","wrong":"const Cropper = require('cropperjs');","symbol":"Cropper","correct":"import Cropper from 'cropperjs';"},{"note":"For type-only imports in TypeScript, use the `type` keyword. This helps avoid bundling unnecessary code.","symbol":"CropperOptions","correct":"import type { CropperOptions } from 'cropperjs';"},{"note":"The core CSS is essential for Cropper.js to render and function correctly. It must be imported or linked.","symbol":"CSS","correct":"import 'cropperjs/dist/cropper.css';"}],"quickstart":{"code":"import Cropper from 'cropperjs';\nimport 'cropperjs/dist/cropper.css';\n\ndocument.addEventListener('DOMContentLoaded', () => {\n  const container = document.createElement('div');\n  container.style.width = '800px';\n  container.style.height = '600px';\n  container.style.margin = '20px auto';\n  container.style.border = '1px solid #ccc';\n  container.style.display = 'flex';\n  container.style.justifyContent = 'center';\n  container.style.alignItems = 'center';\n  document.body.appendChild(container);\n\n  const image = document.createElement('img');\n  image.id = 'image-to-crop';\n  image.src = 'https://picsum.photos/800/600'; // Example image source\n  image.alt = 'Image for cropping';\n  image.style.maxWidth = '100%';\n  image.style.maxHeight = '100%';\n  container.appendChild(image);\n\n  // Wait for the image to load before initializing Cropper\n  image.onload = () => {\n    const cropper = new Cropper(image, {\n      aspectRatio: 16 / 9,\n      viewMode: 1, // 0: no restrictions, 1: restrict to container, 2: restrict to canvas, 3: restrict to image\n      background: false, // Hide the grid background\n      crop(event) {\n        console.log('Crop data:', event.detail);\n      },\n      ready() {\n        console.log('Cropper is ready!');\n      }\n    });\n\n    // Example: Destroy cropper after 10 seconds\n    // setTimeout(() => {\n    //   cropper.destroy();\n    //   console.log('Cropper destroyed.');\n    // }, 10000);\n  };\n});","lang":"typescript","description":"This quickstart demonstrates how to initialize Cropper.js with an image element, including essential CSS and basic configuration options like aspect ratio and view mode, and logs crop events."},"warnings":[{"fix":"Explicitly set `rotatable: true`, `scalable: true`, `skewable: true`, or `translatable: true` in the Cropper options if these features are desired.","message":"In v2.0.0-rc, the default values for `rotatable`, `scalable`, `skewable`, and `translatable` properties on `CropperImage` were changed from `true` to `false`. Features that previously worked out-of-the-box now require explicit enabling through options.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Update your code to use the `dynamic` property instead of `linked` for CropperSelection configurations.","message":"In v2.0.0-rc.0, the `linked` property of `CropperSelection` was renamed to `dynamic`. Any code referencing the `linked` property will break.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure that `cropperjs/dist/cropper.css` is correctly imported in your JavaScript entry point (`import 'cropperjs/dist/cropper.css';`) or linked in your HTML (`<link rel=\"stylesheet\" href=\"node_modules/cropperjs/dist/cropper.css\">`).","message":"Cropper.js relies heavily on its default CSS for correct rendering and functionality. If the UI appears broken or non-functional, it's often due to missing or improperly loaded styles.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Set the `crossorigin=\"anonymous\"` attribute on your `<img>` tag. Additionally, ensure the server hosting the image is configured with appropriate CORS headers (e.g., `Access-Control-Allow-Origin: *` or your specific origin).","message":"When loading images from a different origin (domain, protocol, or port), using `getCroppedCanvas()` will result in a 'Tainted canvases may not be exported' error due to browser security restrictions (CORS).","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add `import 'cropperjs/dist/cropper.css';` to your main JavaScript/TypeScript file or ensure the CSS is included in your HTML.","cause":"Cropper.js CSS file is not loaded, leading to rendering issues or JavaScript errors when the library tries to manipulate non-existent or incorrectly styled elements.","error":"Uncaught TypeError: Cannot read properties of undefined (reading 'appendChild')"},{"fix":"Add the `crossorigin=\"anonymous\"` attribute to your `<img>` tag. Verify the image server is configured to send `Access-Control-Allow-Origin` headers that permit requests from your domain.","cause":"Attempting to export a canvas as an image (e.g., `toDataURL`, `toBlob`) when the image source is from a different origin and CORS headers are not correctly configured.","error":"Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported."},{"fix":"For CommonJS, use `const Cropper = require('cropperjs').default;`. For modern JavaScript modules, stick to `import Cropper from 'cropperjs';` and ensure your bundler (e.g., Webpack, Rollup) or TypeScript configuration (`esModuleInterop: true`) handles default interop correctly.","cause":"Using `require('cropperjs')` directly in a CommonJS environment without accessing the default export.","error":"Cropper is not a constructor"},{"fix":"Inspect your CSS for conflicting rules, particularly `box-sizing` on elements within or around the cropper. Ensure no other scripts are interfering with mouse events. Check if upgrading to a newer Cropper.js version (e.g., v2.1.0 addressed shadow DOM event target issues) resolves the problem.","cause":"This can stem from conflicting global CSS styles (e.g., `box-sizing`), or complex DOM structures like Shadow DOM where event target calculation can be tricky.","error":"Image glitches or crop box appears unstable during drag/resize."}],"ecosystem":"npm"}