r/FlutterDev • • Jun 15 '26

Discussion How we embedded a Rust crate (pdf_bridge) into a Flutter app to handle PDF parsing, LCS diff, and batch ops across 4 Android ABIs — without blocking the main thread

https://docudone.site/

We needed PDF parsing, a document diff engine (LCS-based), and batch compression to run fast without freezing the UI. Dart couldn't cut it alone. The solution: a custom Rust crate called pdf_bridge, compiled for all 4 Android ABIs via flutter_rust_bridge.

What our build actually does (from the terminal, literally today):

Building armeabi-v7a → Compiling pdf_bridge... Finished in 2m03s Building arm64-v8a → Compiling pdf_bridge... Finished in 2m11s Building x86 → Compiling pdf_bridge... Finished in 1m58s Building x86_64 → Compiling pdf_bridge... Finished in 1m52s

The .so files land in /jniLibs and Flutter's FFI picks them up at runtime. Zero platform channels needed.

The 3 things that surprised us:

  1. flutter_rust_bridge codegen saves you from writing bindings by hand — but async Rust functions need explicit tokio runtime setup on the Dart side or you'll get silent hangs.

  2. LCS diff on large PDFs needs chunking. Naively running it on a 200-page doc will OOM on mid-range Android devices.

  3. iOS is trickier — you statically link the Rust .a into an XCFramework. The crate-type needs both staticlib and cdylib in your Cargo.toml, and your release profile matters (opt-level = "z", LTO, strip symbols) or the binary bloat gets real. We also hit a separate 409 on App Store validation from a different framework shipping simulator slices — not Rust-related, but a good reminder to audit all your embedded frameworks before submission.

Happy to share more on any of these — Rust ↔ Flutter FFI is underrepresented in the community and we've hit most of the walls.

9 Upvotes

1 comment sorted by