Integrate Rust with Flutter using flutter_rust_bridge
Flutter is an amazing framework for building apps that work across platforms like Android, iOS, Windows, and more. However, when you need high performance for tasks like image recognition or Optical Character Recognition (OCR), Flutter’s performance may not be enough. This is where Rust comes in handy. Rust is a system programming language designed for speed and safety. In this blog post, we’ll talk about how to integrate Rust code into Flutter using the `flutter_rust_bridge` package. By doing so, we can get the best of both worlds—Flutter's flexibility and Rust’s speed.
Potential Usecases
High-Performance Computing (HPC)
Use Case: Implementing a computationally intensive algorithm like cryptography, signal processing, or scientific simulations.
Example: A secure messaging app using end-to-end encryption could offload encryption and decryption to Rust for optimized performance.
Custom Image and Video Processing
Use Case: Manipulating or analyzing multimedia files, such as applying filters or extracting metadata.
Example: A photo editing app could use Rust to apply complex filters or handle encoding/decoding for custom media formats.
Integrating flutter_rust_bridge with Flutter
Here’s how you can start integrating Rust with Flutter:
- Install
flutter_rust_bridge_codegen
: First, you need to install theflutter_rust_bridge_codegen
tool using Cargo, Rust's package manager:
- Add the Required DependenciesAdd the
flutter_rust_bridge
package as a dependency in yourpubspec.yaml
file:Next, add theffi
package to thedev_dependencies
and configure the plugin settings to enable FFI (Foreign Function Interface) on supported platforms:
Why do you need the ffi
package?
The ffi
package is essential because it allows Dart to interact with native Rust code. It does this by using dynamic libraries (e.g., .dll
for Windows, .so
for Linux, and .dylib
for macOS). Without ffi
, Flutter can’t directly call the native functions from the compiled Rust library. You can manually interface with Rust by writing FFI bindings yourself without using flutter_rust_bridge
but using it is more convenient.
- Create the Configuration FileIn your project root, create a file named
flutter_rust_bridge.yaml
to specify the Rust code location and where the generated Dart code should go: - Set Up the Rust ProjectIn the root folder, initialize a new Rust library project with the following command:This creates a new Rust project inside the
rust/
folder, which will contain the Rust code.

- Structure Your Rust CodeNow, let’s create the necessary Rust code to make it compatible with Flutter. Start by creating an
api.rs
file in yourrust/src
directory. Thelib.rs
file should importapi.rs
and the code generated byflutter_rust_bridge
:
Example: Structuring Your Rust File for Flutter Integration
Below is an example of how to structure your Rust code in a way that is compatible with Flutter using the flutter_rust_bridge
macro.
Under the hood we are using the pdfium_render rust library.
The pdfium.dll
file is required for the library to work on your system. While this file can be installed on the system itself, we can also package it with the application to make things easier. To do this, we need to place the pdfium.dll
into the environment-specific build folder during the build process. This is done by modifying the project's CMakeLists.txt
file.
What is CMake?
CMake is a build tool used to manage the building process of applications, especially for cross-platform development. It helps generate build files specific to the platform you're targeting, like Windows, macOS, or Linux.
To ensure the pdfium.dll
file is included in the build, we can add the following lines to the end of the CMakeLists.txt
:
- SOURCE_DLL: This defines the path where the
pdfium.dll
file is located. Here, it points towindows/include/pdfium.dll
. - BUILD_FOLDER: This defines the path where the
pdfium.dll
will be copied. The destination depends on the environment you're building for.
For example, running:
will place the pdfium.dll
file in the build\\windows\\x64\\runner\\Debug
folder. The install
command handles copying the file to the appropriate location during the build process.
In this example:
- Modules: Rust modules are used to organize different file types (CSV, DOCX, PDF) extraction logic.
flutter_rust_bridge
Macro: The#[flutter_rust_bridge::frb(dart_async)]
macro is added to theextract
function, making it callable from Dart and handling async tasks.- Infer File Type: The
infer
crate is used to determine the file type from the file path and apply the appropriate extraction logic.
- Run Code GenerationOnce your Rust code is set up, you need to run the code generator to create the Dart bindings. In the root folder of your project, run:This will generate Dart code for you in the specified
dart_output
directory (lib/rust
).
/im
- Use the Generated Dart CodeAfter running the code generator, you will find the generated Dart code in the
lib/rust
directory. This code acts as the bridge between Flutter and Rust, allowing you to call Rust functions from your Dart code easily.Example usage of the generated Dart code:
Conclusion
By following these steps, you can harness the power of Rust within your Flutter apps using the flutter_rust_bridge
. This setup allows you to offload performance-critical tasks to Rust, ensuring that your Flutter app stays responsive while handling complex operations efficiently.
Integrating Flutter and Rust is a powerful way to combine Flutter's cross-platform strengths with Rust's performance, giving you the best of both worlds.
You can check out the pdf_ocr package in action here, where you can find an example project for testing.