The Zstandard Flutter plugin follows a federated plugin architecture, where a main package delegates platform-specific work to separate packages while exposing a single unified API to application code.
graph TD
App[Flutter Application]
Main[zstandard<br/>Main Plugin]
Interface[zstandard_platform_interface<br/>Abstract Contract]
App --> Main
Main --> Interface
Interface --> Android[zstandard_android]
Interface --> iOS[zstandard_ios]
Interface --> macOS[zstandard_macos]
Interface --> Linux[zstandard_linux]
Interface --> Windows[zstandard_windows]
Interface --> Web[zstandard_web]
Android --> FFI1[FFI + Native zstd]
iOS --> FFI2[FFI + Native zstd]
macOS --> FFI3[FFI + Native zstd]
Linux --> FFI4[FFI + Native zstd]
Windows --> FFI5[FFI + Native zstd]
Web --> WASM[WebAssembly + zstd.js]
The main package is the only one applications depend on. It:
- Exposes the public API:
Zstandardclass andZstandardExtextension onUint8List? - Uses conditional imports to load either native or web implementation (
ZstandardImpl) - Does not contain platform code; it delegates to the platform interface and registered implementations
Defines the contract all platform implementations must satisfy:
- ZstandardPlatform: Abstract base class with
getPlatformVersion(),compress(), anddecompress() - MethodChannelZstandardPlatform: Default implementation used when no native implementation is registered (e.g. in unit tests); only
getPlatformVersion()is implemented via method channel - Platform packages extend
ZstandardPlatform, implement the three methods, and register themselves viaZstandardPlatform.instance = ...
The C source code of facebook/zstd and the shared FFI bindings live in the zstandard_native package (zstandard_native/src/zstd/ and lib/zstandard_native_bindings.dart). All native platform packages (Android, iOS, macOS, Linux, Windows) and the CLI depend on zstandard_native and use it as the single source of truth for zstd. When building from the repository, scripts and CMake resolve zstandard_native from the repo; when consuming from pub.dev, they resolve it from the pub cache.
| Package | Technology | Notes |
|---|---|---|
| zstandard_android | FFI + JNI | Native zstd from zstandard_native, CMake in zstd_build/ |
| zstandard_ios | FFI | zstd synced from zstandard_native into Classes/zstd/, CocoaPods |
| zstandard_macos | FFI | zstd synced from zstandard_native into Classes/zstd/, CocoaPods |
| zstandard_linux | FFI | Native zstd from zstandard_native, CMake in zstd_build/ |
| zstandard_windows | FFI | Native zstd from zstandard_native, CMake in windows/ |
| zstandard_web | JS interop + WASM | zstd.js / zstd.wasm loaded from web/ (built from zstandard_native in dev) |
Standalone pure Dart package for desktop (macOS, Windows, Linux). It:
- Does not depend on Flutter
- Loads precompiled native zstd libraries per platform/architecture
- Provides the same
compress/decompressAPI and extensions for use in Dart CLI apps ordart run
- Application calls
Zstandard().compress(...)or uses the extension. - The main plugin uses
ZstandardImpl(), which usesPlatformManagerto detect the current platform (kIsWeb,Platform.isAndroid, etc.). - On first access to
instance, the appropriate platform implementation is registered (e.g.ZstandardAndroid.registerWith()) andZstandardPlatform.instanceis set. - All subsequent calls use that registered instance.
Web uses a separate implementation path: ZstandardImpl is conditionally imported from zstandard_impl_web.dart when not on dart:io, and registers the web implementation.
- Compression:
Uint8List→ main plugin → platform instance → native/JS implementation → compressedUint8List? - Decompression: Compressed
Uint8List→ main plugin → platform instance → native/JS implementation → decompressedUint8List?
All APIs are asynchronous (Future<Uint8List?>). On native platforms, heavy work can be offloaded to isolates to avoid blocking the UI.
- Platform Interface — Contract and registration details
- FFI Implementation — Native platform implementation
- Web Implementation — Web platform implementation
- Isolate Pattern — Async compression with isolates