# vue-croppa

> A simple, polished, Vue-native image cropper for upload flows.

Latest version **2.0.0** (published 2026-09-23) · ISC license · 0 weekly downloads

## Install

```sh
npm install vue-croppa
pnpm add vue-croppa
yarn add vue-croppa
bun add vue-croppa
```

## Health

**Score 55/100 (C)** — status: active.

Positive: no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types; no esm support.

## Facts

| | |
|---|---|
| Version | 2.0.0 |
| Published | 2026-09-23 |
| First published | 2017-06-15 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 955 |
| Maintainers | zhanziyang |

## Links

- npm: https://www.npmjs.com/package/vue-croppa
- npm.io page: https://npm.io/package/vue-croppa

## Recent versions

- 2.0.0 (latest) — 2026-09-23
- 1.3.8 — 2018-08-16
- 1.3.7 — 2018-07-16
- 1.3.6 — 2018-04-19
- 1.3.5 — 2018-04-19
- 1.3.4 — 2018-04-15
- 1.3.3 — 2018-04-08
- 1.3.2 — 2018-04-06
- 1.3.1 — 2018-04-06
- 1.3.0 — 2018-03-13
- 1.2.1 — 2018-02-28
- 1.2.0 — 2018-01-28
- 1.1.5 — 2017-12-25
- 1.1.4 — 2017-12-01
- 1.1.3 — 2017-11-19
- … 46 more at https://npm.io/package/vue-croppa/versions

## README

# vue-croppa v2

This directory contains the `vue-croppa` package for Vue 3. Vue 2 consumers can stay on the `1.x` release line.

## Product direction

v2 is intentionally focused on upload-oriented image cropping: load an image, position/zoom it inside a crop viewport, and export or persist the crop. It is not intended to become a general-purpose image editor.

## Interaction contract

The v2 rewrite preserves vue-croppa's defining WYSIWYG interaction model:

- The crop viewport is fixed and represents the exact output.
- The user moves and zooms the **image underneath the viewport**.
- There is no draggable or resizable crop-selection rectangle over the source image.
- Crop size/aspect is controlled by component configuration/layout, not by corner handles.
- Rotation and flips transform the image under the same fixed viewport.
- Exported pixels must match what is visible inside the viewport.
- `CropState.crop` is an internal source-relative representation of what the fixed viewport currently sees; it is not the UI interaction model.

This is a product-level invariant for v2, not a compatibility detail.

## Compatibility rule

v2 is a rewrite, not a feature reset. Existing v1 user capabilities are retained by default; any removal requires an explicit, separately reviewed decision.

The full inventory and migration requirements live in [COMPATIBILITY.md](./COMPATIBILITY.md).

In particular, v1 allows whitespace by default. Therefore `CropState` must be able to represent source-relative rectangles outside the `0..1` source bounds. `preventWhiteSpace` is an interaction constraint, not a fundamental limitation of the state model.

## Foundation principles

- Vue 3 + TypeScript.
- Pure geometry/state logic is framework-independent and testable without a browser.
- Crop state is serializable and independent of the rendered viewport size.
- Display size, canvas backing resolution, and export dimensions are separate concepts.
- Pointer Events, `ResizeObserver`, and modern browser APIs replace the legacy mouse/touch/polyfill stack.
- The original source image stays immutable; rotation and flips are transformations, not re-encoding steps.
- v1 compatibility is handled through migration guidance/adapters rather than preserving v1 internals.

## State model

The foundation uses a normalized crop rectangle plus image transforms:

```ts
interface CropState {
  crop: {
    x: number
    y: number
    width: number
    height: number
  }
  rotation: 0 | 90 | 180 | 270
  flipX: boolean
  flipY: boolean
}
```

`crop` is expressed against the currently oriented source image in normalized source units. The source itself occupies `0..1`, but the crop may use negative coordinates or dimensions greater than `1` when whitespace is visible. This preserves v1 behavior while keeping state stable across responsive layout changes and suitable for persistence or server-side reproduction.

## Component

The Vue 3 `Croppa` component mounts a real image loader, fixed canvas viewport, Pointer Events interactions, remove control, and Blob/data URL export on the foundation core. File drop follows v1's default rule: it fills an empty viewport, and replaces an existing image only when `replaceDrop` is true. The component also supports the v1 disabled and per-interaction flags, reverse wheel direction, and `inputAttrs`. The docs preview mounts this component. [COMPATIBILITY.md](./COMPATIBILITY.md) records the migration contract.

Basic usage:

```vue
<script setup lang="ts">
import { ref } from 'vue'
import { Croppa } from 'vue-croppa'

const cropper = ref<InstanceType<typeof Croppa> | null>(null)
</script>

<template>
  <Croppa ref="cropper" :width="320" :height="320" initial-size="cover" />
  <button @click="cropper?.promisedBlob('image/png')">Export</button>
</template>
```

The component exposes `chooseFile()`, `setFile(file)`, `remove()`, `move()` and directional helpers, `zoom()` / `zoomIn()` / `zoomOut()`, `rotate(step)`, `flipX()`, `flipY()`, `getCanvas()`, `getContext()`, `addClipPlugin()`, `generateDataUrl()`, `generateBlob(callback)`, and `promisedBlob()`. It emits `init`, `draw`, `loading-start`, and `loading-end` at the corresponding lifecycle points, plus `load-error` when decoding fails. `showLoading`, `loadingSize`, and `loadingColor` control the optional indicator.

`getMetadata()` returns versioned v2 state. `applyMetadata(metadata)` accepts both v2 metadata and v1 `{ startX, startY, scale, orientation }` metadata. It can queue metadata before an image loads. v2 restoration requires the same source dimensions and viewport aspect ratio. See [MIGRATION.md](./MIGRATION.md) for the Vue 2 to Vue 3 API changes.

Import `vue-croppa/style.css` with the component. The default export supports `app.use(VueCroppa, { componentName: 'croppa' })`; `Croppa` is also a named export. `v-model` shares an in-memory image and crop state with a `passive` preview. `autoSizing` uses `ResizeObserver`, and `videoEnabled` accepts supported video files and lets the user toggle playback with a double click.

## Commands

Requires Node.js 22.12 or newer.

```bash
npm install
npm run check
```

---
_Source: https://npm.io/package/vue-croppa · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
