{"_id":"@bayinformatics/croppie","_rev":"3-43bf0c42317caafa003cfed8ec9a1793","name":"@bayinformatics/croppie","dist-tags":{"latest":"3.1.0"},"versions":{"3.0.0":{"name":"@bayinformatics/croppie","version":"3.0.0","keywords":["image","crop","cropper","avatar","resize","canvas","typescript"],"author":{"name":"Bay Informatics"},"license":"MIT","_id":"@bayinformatics/croppie@3.0.0","maintainers":[{"name":"bayinformatics","email":"matthew@bayinformatics.com"}],"homepage":"https://github.com/bayinformatics/croppie#readme","bugs":{"url":"https://github.com/bayinformatics/croppie/issues"},"dist":{"shasum":"88aff352327b1ed72f62036f39d604da137ffdef","tarball":"https://registry.npmjs.org/@bayinformatics/croppie/-/croppie-3.0.0.tgz","fileCount":68,"integrity":"sha512-y8DmSYwfNhr7UOPrhGMyGESPlyB59yE2c8SVjlSy9rJxruqe1GSUKzWPLSS5LreZRzrL3ZHqUgPvH7A5+YuSiQ==","signatures":[{"sig":"MEQCICf1Am3tBON935cXZxiuLsHk3xwK5P2Np61j5chyEV6EAiAo0nnxgoHhHw9J2kN+OGXcyz9HpMHry/nPj5Wu24V1Wg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bayinformatics%2fcroppie@3.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":166116},"main":"./dist/croppie.js","type":"module","types":"./dist/index.d.ts","module":"./dist/croppie.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/croppie.js","require":"./dist/croppie.cjs"},"./style.css":"./dist/croppie.css","./croppie.css":"./dist/croppie.css"},"gitHead":"c94ba7ebf93129fb96ee943e1213c175a319c2a7","scripts":{"dev":"bun build src/index.ts --outdir dist --watch","lint":"bunx biome check src","test":"bun test","build":"bun run build:js && bun run build:css && bun run build:types","build:js":"bun build src/index.ts --outdir=dist --entry-naming=croppie.[ext] --minify --sourcemap","lint:fix":"bunx biome check --write src","test:all":"bun test && bunx playwright test","build:css":"cp src/croppie.css dist/croppie.css","test:unit":"bun test tests/unit","test:watch":"bun test --watch","build:types":"tsc --emitDeclarationOnly --declaration --outDir dist","test:visual":"bunx playwright test","prepublishOnly":"bun run build","test:integration":"bun test tests/integration"},"_npmUser":{"name":"bayinformatics","email":"matthew@bayinformatics.com"},"repository":{"url":"git+https://github.com/bayinformatics/croppie.git","type":"git"},"_npmVersion":"10.8.2","description":"A modern, TypeScript-first image cropper. Fork of Foliotek/Croppie.","directories":{},"_nodeVersion":"20.19.6","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"happy-dom":"^20.0.11","@types/bun":"^1.3.0","typescript":"^5.9.0","@biomejs/biome":"^1.9.0","@playwright/test":"^1.57.0"},"_npmOperationalInternal":{"tmp":"tmp/croppie_3.0.0_1766608029910_0.28585987471462815","host":"s3://npm-registry-packages-npm-production"}},"3.0.2":{"name":"@bayinformatics/croppie","version":"3.0.2","keywords":["image","crop","cropper","avatar","resize","canvas","typescript"],"author":{"name":"Bay Informatics"},"license":"MIT","_id":"@bayinformatics/croppie@3.0.2","maintainers":[{"name":"bayinformatics","email":"matthew@bayinformatics.com"}],"homepage":"https://github.com/bayinformatics/croppie#readme","bugs":{"url":"https://github.com/bayinformatics/croppie/issues"},"dist":{"shasum":"fee5e8b02aab7ba130728f7d05ac48e46e3c422b","tarball":"https://registry.npmjs.org/@bayinformatics/croppie/-/croppie-3.0.2.tgz","fileCount":66,"integrity":"sha512-/EdDghRJsLF739ylrrNto60yccfSMhTZAJtAG7L2dLxKzBZMIqAah844Q1qOx6TBll4jRLW3Q/5ktlu8G7yFVw==","signatures":[{"sig":"MEUCIF0khmOJW47twM0P40zhRxi2K6j7jeCZHMfgiVNNRUTyAiEAnqy220hZ7HaBIKKottcs4TWh/zChr29RcHYznrASeeA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bayinformatics%2fcroppie@3.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":142480},"main":"./dist/croppie.js","type":"module","types":"./dist/index.d.ts","module":"./dist/croppie.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/croppie.js"},"./style.css":"./dist/croppie.css","./croppie.css":"./dist/croppie.css"},"gitHead":"5c1837c831842a94bc8f274a0bca9922631bacc6","scripts":{"dev":"bun build src/index.ts --outdir dist --watch","lint":"bunx biome check src","test":"bun test","build":"bun run build:js && bun run build:css && bun run build:types","build:js":"bun build src/index.ts --outdir=dist --entry-naming=croppie.[ext] --minify --sourcemap","lint:fix":"bunx biome check --write src","test:all":"bun test && bunx playwright test","build:css":"cp src/croppie.css dist/croppie.css","test:unit":"bun test tests/unit","test:watch":"bun test --watch","build:types":"tsc --emitDeclarationOnly --declaration --outDir dist","test:visual":"bunx playwright test","prepublishOnly":"bun run build","test:integration":"bun test tests/integration"},"_npmUser":{"name":"bayinformatics","email":"matthew@bayinformatics.com"},"repository":{"url":"git+https://github.com/bayinformatics/croppie.git","type":"git"},"_npmVersion":"10.8.2","description":"A modern, TypeScript-first image cropper. Fork of Foliotek/Croppie.","directories":{},"_nodeVersion":"20.19.6","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"happy-dom":"^20.0.11","@types/bun":"^1.3.0","typescript":"^5.9.0","@biomejs/biome":"^1.9.0","@playwright/test":"^1.57.0"},"_npmOperationalInternal":{"tmp":"tmp/croppie_3.0.2_1766612188956_0.8291896300306372","host":"s3://npm-registry-packages-npm-production"}},"3.1.0":{"name":"@bayinformatics/croppie","version":"3.1.0","description":"A modern, TypeScript-first image cropper. Fork of Foliotek/Croppie.","type":"module","main":"./dist/croppie.js","module":"./dist/croppie.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/croppie.js"},"./croppie.css":"./dist/croppie.css","./style.css":"./dist/croppie.css"},"scripts":{"dev":"bun build src/index.ts --outdir dist --watch","build":"bun run build:js && bun run build:css && bun run build:types","build:js":"bun build src/index.ts --outdir=dist --entry-naming=croppie.[ext] --minify --sourcemap","build:css":"cp src/croppie.css dist/croppie.css","build:types":"tsc --emitDeclarationOnly --declaration --outDir dist","test":"bun test","test:unit":"bun test tests/unit","test:integration":"bun test tests/integration","test:visual":"bunx playwright test","test:all":"bun test && bunx playwright test","test:watch":"bun test --watch","lint":"bunx biome check src","lint:fix":"bunx biome check --write src","prepublishOnly":"bun run build"},"keywords":["image","crop","cropper","avatar","resize","canvas","typescript"],"author":{"name":"Bay Informatics"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bayinformatics/croppie.git"},"bugs":{"url":"https://github.com/bayinformatics/croppie/issues"},"homepage":"https://github.com/bayinformatics/croppie#readme","devDependencies":{"@biomejs/biome":"^1.9.0","@playwright/test":"^1.57.0","@types/bun":"^1.3.0","happy-dom":"^20.0.11","typescript":"^5.9.0"},"engines":{"node":">=18"},"publishConfig":{"access":"public"},"_id":"@bayinformatics/croppie@3.1.0","gitHead":"7795d873ca12ff896a7c98b9950e83590878b7c1","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-rr7ugvtTbVNbDp1N6hZ57/QwdVXkGUFeNwW5YYahpSytqIBiBl6fmQNdPLdZ4dgssu57AgIpK282hsX8e0a3RQ==","shasum":"8571553d59f118b3d8e3f95f3597900761fb63b6","tarball":"https://registry.npmjs.org/@bayinformatics/croppie/-/croppie-3.1.0.tgz","fileCount":68,"unpackedSize":146972,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bayinformatics%2fcroppie@3.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCmlN6sPz9KDzXS3b7Vy0aJ0aSWMbo89ETHcvQNoqUjWAIgI7EGXY/6n1oY8FvK+VLjt7VwkC6rI3ln+2Kt/aD5Q80="}]},"_npmUser":{"name":"bayinformatics","email":"matthew@bayinformatics.com"},"directories":{},"maintainers":[{"name":"bayinformatics","email":"matthew@bayinformatics.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/croppie_3.1.0_1767635192701_0.6810787768914661"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-24T20:27:09.780Z","modified":"2026-01-05T17:46:33.308Z","3.0.0":"2025-12-24T20:27:10.048Z","3.0.2":"2025-12-24T21:36:29.139Z","3.1.0":"2026-01-05T17:46:32.854Z"},"bugs":{"url":"https://github.com/bayinformatics/croppie/issues"},"author":{"name":"Bay Informatics"},"license":"MIT","homepage":"https://github.com/bayinformatics/croppie#readme","keywords":["image","crop","cropper","avatar","resize","canvas","typescript"],"repository":{"type":"git","url":"git+https://github.com/bayinformatics/croppie.git"},"description":"A modern, TypeScript-first image cropper. Fork of Foliotek/Croppie.","maintainers":[{"name":"bayinformatics","email":"matthew@bayinformatics.com"}],"readme":"# @bayinformatics/croppie\n\nA modern, TypeScript-first image cropper. Fork of [Foliotek/Croppie](https://github.com/Foliotek/Croppie).\n\n## Why This Fork?\n\nThe original Croppie hasn't been updated since 2019 and has 270+ open issues. This fork modernizes the codebase with:\n\n- 🦕 **ES Modules** - Native ESM, no more IIFE/UMD wrappers\n- 📘 **TypeScript** - Full type definitions included\n- 🔧 **Modern APIs** - Pointer Events, no polyfills needed\n- 🪶 **Smaller Bundle** - Tree-shakeable, ~15KB gzipped (target)\n- 📱 **Mobile First** - Touch and gesture support built-in\n- 🧪 **Tested** - Unit and visual regression tests\n\n## Installation\n\n```bash\n# npm\nnpm install @bayinformatics/croppie\n\n# pnpm\npnpm add @bayinformatics/croppie\n\n# bun\nbun add @bayinformatics/croppie\n```\n\n## Compatibility\n\nThis is an **ESM-only** package. It works with modern bundlers like Vite, Webpack, Rollup, Next.js, and Bun.\n\n**Breaking Change in v3:** CommonJS `require()` is no longer supported. If you need CommonJS, continue using [Croppie v2.x](https://github.com/Foliotek/Croppie).\n\n```diff\n- const Croppie = require('croppie')\n+ import Croppie from '@bayinformatics/croppie'\n```\n\n**For `<script>` tag usage without a bundler, this fork is not for you** — use the original [Croppie v2.x](https://github.com/Foliotek/Croppie) instead.\n\n## Quick Start\n\n```typescript\nimport Croppie from '@bayinformatics/croppie'\nimport '@bayinformatics/croppie/croppie.css'\n\nconst cropper = new Croppie(document.getElementById('cropper')!, {\n  viewport: { width: 200, height: 200, type: 'circle' }\n})\n\n// Load an image\nawait cropper.bind({ url: 'photo.jpg' })\n\n// Get the cropped result\nconst blob = await cropper.result({ type: 'blob' })\n```\n\n## API\n\n### Constructor\n\n```typescript\nnew Croppie(element: HTMLElement, options: CroppieOptions)\n```\n\n### Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `viewport` | `{ width, height, type }` | Required | Crop area dimensions and shape (`'circle'` or `'square'`) |\n| `boundary` | `{ width, height }` | viewport + 100px | Container dimensions |\n| `showZoomer` | `boolean` | `true` | Show zoom slider |\n| `mouseWheelZoom` | `boolean \\| 'ctrl'` | `true` | Enable scroll zoom (optionally require Ctrl key) |\n| `zoom` | `{ min, max }` | `{ min: 0.1, max: 10 }` | Zoom limits |\n\n### Methods\n\n#### `bind(options: BindOptions | string): Promise<void>`\n\nLoad an image into the cropper.\n\n```typescript\n// Simple URL\nawait cropper.bind('photo.jpg')\n\n// With options\nawait cropper.bind({\n  url: 'photo.jpg',\n  zoom: 1.5,\n  points: { topLeftX: 0, topLeftY: 0, bottomRightX: 200, bottomRightY: 200 }\n})\n```\n\n#### `bindFile(file: File | Blob): Promise<void>`\n\nLoad an image from a File input.\n\n```typescript\nconst input = document.querySelector('input[type=\"file\"]')\ninput.addEventListener('change', async (e) => {\n  const file = e.target.files[0]\n  await cropper.bindFile(file)\n})\n```\n\n#### `result(options: ResultOptions): Promise<Blob | string | HTMLCanvasElement>`\n\nGet the cropped result.\n\n```typescript\n// Get as Blob (for uploading)\nconst blob = await cropper.result({ type: 'blob', format: 'png' })\n\n// Get as base64 (for preview)\nconst base64 = await cropper.result({ type: 'base64', format: 'jpeg', quality: 0.9 })\n\n// Get as Canvas (for further manipulation)\nconst canvas = await cropper.result({ type: 'canvas' })\n\n// Custom output size\nconst blob = await cropper.result({\n  type: 'blob',\n  size: { width: 400, height: 400 }\n})\n```\n\n#### `get(): CroppieData`\n\nGet current crop data (points and zoom).\n\n#### `setZoom(value: number): void`\n\nSet the zoom level programmatically.\n\n#### `reset(): void`\n\nReset to initial state.\n\n#### `destroy(): void`\n\nClean up and remove the cropper.\n\n### Events\n\n```typescript\ncropper.on('update', (data) => {\n  console.log('Crop changed:', data.points, data.zoom)\n})\n\ncropper.on('zoom', ({ zoom, previousZoom }) => {\n  console.log(`Zoom: ${previousZoom} → ${zoom}`)\n})\n```\n\n## Migrating from Croppie v2\n\n### Quick Reference\n\n| v2 (Original) | v3 (This Fork) |\n|---------------|----------------|\n| `$('#el').croppie({...})` | `new Croppie(element, {...})` |\n| `croppie.bind(url)` | `await croppie.bind(url)` |\n| `croppie.bind({ url, points: [x1,y1,x2,y2] })` | `await croppie.bind({ url, points: {topLeftX, topLeftY, bottomRightX, bottomRightY} })` |\n| `croppie.result({...}).then(cb)` | `const result = await croppie.result({...})` |\n| `$el.on('update', cb)` | `croppie.on('update', cb)` |\n| `import 'croppie/croppie.css'` | `import '@bayinformatics/croppie/croppie.css'` |\n\n### Detailed Changes\n\n```diff\n- import Croppie from 'croppie'\n+ import Croppie from '@bayinformatics/croppie'\n\n- import 'croppie/croppie.css'\n+ import '@bayinformatics/croppie/croppie.css'\n\n// result() now returns a Promise for all types\n- cropper.result({ type: 'canvas' }).then(canvas => {})\n+ const canvas = await cropper.result({ type: 'canvas' })\n\n// Points format changed\n- points: [x1, y1, x2, y2]\n+ points: { topLeftX, topLeftY, bottomRightX, bottomRightY }\n```\n\n## Framework Examples\n\n### Stimulus (Hotwire)\n\n```typescript\nimport { Controller } from '@hotwired/stimulus'\nimport Croppie from '@bayinformatics/croppie'\n\nexport default class extends Controller {\n  static targets = ['input', 'preview']\n\n  croppie?: Croppie\n\n  connect() {\n    this.croppie = new Croppie(this.previewTarget, {\n      viewport: { width: 200, height: 200, type: 'circle' }\n    })\n  }\n\n  async selectFile(event: Event) {\n    const file = (event.target as HTMLInputElement).files?.[0]\n    if (file) await this.croppie?.bindFile(file)\n  }\n\n  async crop() {\n    return this.croppie?.result({ type: 'blob' })\n  }\n\n  disconnect() {\n    this.croppie?.destroy()\n  }\n}\n```\n\n### React\n\n```tsx\nimport { useRef, useEffect } from 'react'\nimport Croppie from '@bayinformatics/croppie'\n\nfunction ImageCropper({ src, onCrop }) {\n  const containerRef = useRef<HTMLDivElement>(null)\n  const croppieRef = useRef<Croppie>()\n\n  useEffect(() => {\n    if (containerRef.current) {\n      croppieRef.current = new Croppie(containerRef.current, {\n        viewport: { width: 200, height: 200, type: 'circle' }\n      })\n      croppieRef.current.bind(src)\n    }\n    return () => croppieRef.current?.destroy()\n  }, [src])\n\n  const handleCrop = async () => {\n    const blob = await croppieRef.current?.result({ type: 'blob' })\n    onCrop(blob)\n  }\n\n  return (\n    <div>\n      <div ref={containerRef} />\n      <button onClick={handleCrop}>Crop</button>\n    </div>\n  )\n}\n```\n\n## Development\n\n```bash\n# Install dependencies\nbun install\n\n# Run dev server with watch\nbun run dev\n\n# Run tests\nbun test\n\n# Build for production\nbun run build\n\n# Lint\nbun run lint\n```\n\n## License\n\nMIT - See [LICENSE](./LICENSE)\n\nOriginal work Copyright (c) 2015 Foliotek Inc.\nModified work Copyright (c) 2025 Bay Informatics\n\n## Credits\n\nThis project is a fork of [Croppie](https://github.com/Foliotek/Croppie) by Foliotek. Thanks to the original authors for their work!\n","readmeFilename":"README.md"}