The web platform cannot use Dart FFI. Instead, zstandard_web uses JavaScript and WebAssembly: the Zstandard C library is compiled to WASM with Emscripten, and Dart calls into it via JS interop.
graph LR
Dart[zstandard_web Dart]
JS[zstd.js]
WASM[zstd.wasm]
Dart -->|dart:js_interop| JS
JS --> WASM
- zstd.js: Emscripten-generated JS glue that loads and initializes the WASM module and exposes functions like
compressDataanddecompressData. - zstd.wasm: Compiled zstd C code (compression, decompression, bounds, frame size).
- Dart: Uses
dart:js_interop(andpackage:web) to call the JS functions and passUint8Listdata.
| Aspect | Native (FFI) | Web (JS/WASM) |
|---|---|---|
| Entry point | C functions via FFI | JS functions compressData / decompressData |
| Threading | Can use Dart isolates | No isolates for WASM; work runs on main thread or in workers if implemented |
| Memory | Dart + native malloc/free | JS typed arrays + WASM linear memory |
| Build | CMake / Gradle / Xcode | Emscripten (emcc) build of zstd |
The web implementation does not use the same isolate-based async helpers as native; it awaits the JS interop calls that run the WASM compression/decompression.
- Assets: Copy
zstd.jsandzstd.wasminto the Flutter web project (e.g.web/directory). The exact paths are documented in Platforms — Web. - HTML: Include the script in your
web/index.htmlso the WASM module is loaded before the app runs:<script src="zstd.js"></script>
- Initialization: The Emscripten module must be loaded and ready before any call to
compressordecompress. The web implementation assumes the global functions exist when invoked.
The Dart code expects the following in the global scope (or on a known object):
-
compressData(inputData, compressionLevel)
inputData:Uint8ArraycompressionLevel: number (1–22)- Returns:
Uint8Array(compressed) ornullon error
-
decompressData(compressedData)
compressedData:Uint8Array- Returns:
Uint8Array(decompressed) ornullon error
Dart converts between Uint8List and JS typed arrays via dart:js_interop so that the same Uint8List API is used across all platforms.
zstd is built with Emscripten. High-level steps:
- Install and activate Emscripten SDK.
- Clone the facebook/zstd repository.
- Run
emccon the zstd sources with flags for WASM, exported functions (ZSTD_compress,ZSTD_decompress,ZSTD_compressBound,ZSTD_getFrameContentSize,malloc,free), and output name. - Add the wrapper functions
compressDataanddecompressDatainzstd.js(or a separate script) that allocate buffers, call the exported C functions, and return the result or null.
Detailed commands and wrapper code are in the zstandard_web README and in Platforms — Web.
Some web implementations may return the original data unchanged when the input is very small (e.g. < 9 bytes) because zstd has a minimum frame size. The Dart implementation may handle this by returning the input as-is for both compress and decompress in those cases. See the package source and Platforms — Web for the exact behavior.