Skip to content
All work
OPEN SOURCE2025

image_cropper_widget

A Flutter cropper with no platform channel: pure Dart, so it behaves identically everywhere.

A pure Dart image cropping package for Flutter. No platform-native dependency means no method channel, no per-platform divergence and no added binary weight, with flip, rotate and aspect-ratio locking implemented as widget-tree transformations.

The problem

The established Flutter croppers wrap native UIKit and Android libraries. That brings three costs an app pays forever: binary size, a method-channel boundary that makes deep UI customisation impractical, and two separate behaviours to test because the iOS and Android cropper are genuinely different products. Doing it in Dart removes all three, provided the transformation maths and gesture handling are good enough to feel native anyway.

The approach

  • No platform channel

    The entire cropping surface is a Flutter widget. One implementation, one behaviour, one set of tests, and it works anywhere Flutter runs, including web and desktop, which the native wrappers do not.

  • Transformations as matrix maths

    Flip, rotate and aspect-ratio locking composed as coordinate transformations in the widget tree, so the crop rectangle stays correct under any combination of them.

  • A styleable overlay

    Handles, grid and overlay are injectable, so the cropper can be made to look like the host app rather than like someone else's design system.

System architecture

How it is put together

  1. Gesture layer

    Pan, pinch and handle drags resolved against the current transformation

  2. Transform core

    Composed flip, rotate and aspect-lock matrices keeping the crop rect valid

  3. Overlay

    Injectable handle, grid and mask widgets for host-app styling

Engineering decisions

The calls worth defending

Pure Dart is a distribution decision, not a purity one

A package that binds to native code inherits every platform's release cycle and every consumer's build configuration. A package that does not runs everywhere Flutter runs and can be reviewed in one read.

Interface

What shipped

  • image_cropper_widget: Cropper interface

    Cropper interface

    The widget, with default overlay styling