flutter_image_compress: compression that runs in the platform's own encoder
Compresses image with native plugin (ObjC/Kotlin) on Flutter. Works on Android, iOS, macOS, Web, OpenHarmony.
At a glance
- What is it?
- flutter_image_compress is a Flutter plugin that compresses images by calling native encoders, Kotlin on Android and Objective-C or Swift on Apple platforms, rather than doing the work in Dart. It covers Android, iOS, macOS, Web and OpenHarmony, with a feature matrix that shows exactly where the platforms diverge.
- Who is it for?
- Adopt flutter_image_compress if your Flutter app compresses user photos and the Dart-only libraries are too slow for that workload, since the plugin exists to hand compression to the platform encoder and the README says that is dramatically faster. Do not adopt it if you need a single identical behaviour everywhere, because the feature matrix shows Web missing file based entry points, rotation and EXIF retention, and macOS missing WebP output.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why the plugin exists instead of a Dart library
The README has a section titled Why native instead of Dart, and the argument is short. Dart-only image libraries exist, but in practice they are too slow for typical compression workloads, even in release builds, and even when moved to an Isolate. Delegating to platform-native encoders is dramatically faster, in the README's wording. That is the entire design rationale, and it explains the shape of the package: a thin Dart API over an Android implementation in Kotlin and an Apple implementation in Objective-C or Swift. The project is a Flutter plugin published on pub.dev, MIT licensed, with the primary language Dart, and it covers Android, iOS, macOS, Web and OpenHarmony. The release tags show a multi-package layout, with flutter_image_compress at v2.5.1 and flutter_image_compress_common at v1.1.1, both dated 2026-07-25, alongside a separate flutter_image_compress_web at v0.1.5+1.
Four entry points, and the difference between them
The plugin exposes four ways in, and the choice is about what you have and what you want back. compressWithFile takes a file and returns bytes, compressAndGetFile takes a file and a target path and returns a file, compressAssetImage works on an asset bundled with the app and returns bytes, and compressWithList takes a Uint8List and returns bytes. The README's worked examples make the shapes concrete.
// 1. Compress a file, get bytes back.
Future<Uint8List?> testCompressFile(File file) async {
final result = await FlutterImageCompress.compressWithFile(
file.absolute.path,
minWidth: 2300,
minHeight: 1500,
quality: 94,
rotate: 90,
);
print(file.lengthSync());
if (result != null) {
print(result.length);
}
return result;
}The file based methods are the ones that matter for user photos, and the asset and list methods cover the other two common cases, images shipped with the app and images already in memory.
Installing the package in a Flutter project
Adding the dependency is the standard two ways. The README says to add the latest version to your pubspec.yaml.
dependencies:
flutter_image_compress: <latest_version>Or you can let the tool do it.
flutter pub add flutter_image_compressThen you import the package in your Dart code.
import 'package:flutter_image_compress/flutter_image_compress.dart';The full runnable example lives in the package's example directory, with the README pointing at packages/flutter_image_compress/example/lib/main.dart for a version you can copy.
The platform matrix, and where the gaps are
The feature table is the most useful part of the README, because it is explicit about divergence rather than claiming parity. compressWithList, compressAssetImage, and the jpeg and png formats are supported everywhere, on Android, iOS, Web, macOS and OpenHarmony. compressWithFile and compressAndGetFile are missing on Web, which makes sense for a browser where the file system is not yours to write. WebP output is listed with a browser compatibility caveat on Web and is marked unsupported on macOS. HEIC is available on Android, iOS, macOS and OpenHarmony but not on Web. The rotate parameter is unavailable on Web, and keepExif is available everywhere except OpenHarmony. A plugin that publishes its gaps this plainly is easier to plan around than one that claims uniform support and fails at runtime, and the practical advice is to read the row for your own parameter across your own platform list before you design the feature around it.
minWidth and minHeight are bounds, and the names mislead
The README has an FAQ entry asking why minWidth and minHeight are named that if they act like a max, which is an admission that the naming is confusing. The parameters bound the output size while preserving the source aspect ratio, and the scale is computed from the larger of the two ratios, clamped so it is never below 1. The README gives a Dart port of the native logic as an illustration.
double calcScale({
required double srcWidth,
required double srcHeight,
required double minWidth,
required double minHeight,
}) {
final scaleW = srcWidth / minWidth;
final scaleH = srcHeight / minHeight;
return math.max(1.0, math.min(scaleW, scaleH));
}So a 4000 by 2000 source with minWidth 1920 and minHeight 1080 gives a scale of 1.85 and a target of 2160 by 1080, and if the source is already smaller than the bounds the scale is clamped to 1 and the image is never upscaled. The parameter names describe the floor on each dimension rather than a ceiling, which is why an image can end up larger than one of the two numbers you passed in.
Quality, format, sampling and metadata
The remaining parameters cover the decisions you would otherwise make by hand in a photo editor. quality sets the encoder quality. format selects the output format, with the README giving WebP and HEIF or HEIC their own subsections. inSampleSize subsamples the source before encoding. rotate turns the output by a number of degrees, and zero skips rotation. autoCorrectionAngle, available since 0.5.0, defaults to true and reads the source's EXIF orientation so the output comes out upright, and the README notes that if you also pass a non-zero rotate value the two can conflict. keepExif controls whether EXIF metadata is preserved in the output. There is also a section on EXIF metadata generally, and one on return values that explains working with List<int> and Uint8List, which matters if you are bridging the plugin to a platform channel that expects one of the two.
Where the plugin stops, and what to use instead
Three limits are worth planning around. The first is that compression is not a free lunch: the plugin trades a native call for a platform channel round trip, and on Web the implementation is a separate package, flutter_image_compress_web, which is a different codebase with a different feature set. The second is the format matrix, and specifically that macOS has no WebP output in this package, so an app that needs one encoded format everywhere will need a fallback. The third is scope: this is a compressor, not an image processing library, so if you need cropping, filtering or watermarking you are reaching for a different tool and the only overlap is that both produce a decoded bitmap. The alternative worth comparing is the Dart-only path the README dismisses, which is to use a pure Dart encoder and accept the speed, or to move the work off the UI isolate yourself rather than relying on the plugin, and the plugin's own argument is that neither is competitive for typical compression workloads.
Maintenance, tooling and the repository layout
The repository is not archived, and the last push was on 2026-10-18, so the packages are being worked on. The version numbers tell a useful story about the layout: the main package sits at 2.5.1 and the shared package at 1.1.1, released on the same day, while the web implementation is at 0.1.5+1 and carries a build suffix, which is the pub convention for a package published from a federated plugin. The tree explains the rest. There is a packages/ directory holding the federated packages, a root pubspec.yaml, a melos.yaml for the monorepo tooling, analysis_options.yaml for the Dart analyzer, a CHANGELOG.md, a CODEOWNERS file, a CONTRIBUTING.md, a migrate.md for version migration notes, and a .markdownlint.jsonc for the documentation. The primary language of the repository is Dart, the licence is MIT, and the package is published on pub.dev at the flutter_image_compress address.
Editorial conclusion
Adopt flutter_image_compress if your Flutter app compresses user photos and the Dart-only libraries are too slow for that workload, since the plugin exists to hand compression to the platform encoder and the README says that is dramatically faster. Do not adopt it if you need a single identical behaviour everywhere, because the feature matrix shows Web missing file based entry points, rotation and EXIF retention, and macOS missing WebP output. Before you ship, check the platform matrix against the platforms you support, and read the FAQ note about the minWidth and minHeight names before you rely on them to bound an image.
Frequently asked questions
Why does flutter_image_compress use native code instead of Dart?
The README says Dart-only image libraries exist but in practice they are too slow for typical compression workloads, even in release builds and even when moved to an Isolate. Delegating to platform-native encoders is dramatically faster, with Kotlin on Android and Objective-C or Swift on Apple platforms.
Which platforms does flutter_image_compress support?
The plugin supports Android, iOS, macOS, Web and OpenHarmony, with a feature matrix in the README showing where they differ. The file based methods compressWithFile and compressAndGetFile are not available on Web, rotate is not available on Web, keepExif is not available on OpenHarmony, and WebP output is marked unsupported on macOS.
How do I add flutter_image_compress to a Flutter project?
Add the latest version to your pubspec.yaml under dependencies, or run flutter pub add flutter_image_compress, then import the package in your Dart code with the package:flutter_image_compress/flutter_image_compress.dart import.
What entry points does flutter_image_compress expose?
Four: compressWithFile and compressAndGetFile for files, compressAssetImage for images bundled as assets, and compressWithList for bytes already in memory. Each returns bytes except compressAndGetFile, which writes to a target path and returns a file.
How do minWidth and minHeight behave in flutter_image_compress?
They bound the output size while preserving the source aspect ratio, despite the names suggesting a maximum. The scale is the larger of the two ratios clamped to a minimum of 1, so an image is never upscaled, and the README has an FAQ entry explaining why the names are misleading.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/fluttercandies-flutter-image-compress)Was this useful?