Boost Flutter App Performance with Rust
by Daniel Zelei
Nov 29
4 min read
66 views
You use your favorite cross-platform framework, but you feel the need for extra performance. This is where combining your mobile framework with Rust comes in handy!
In one of our previous blogs, we covered how to combine React Native and Rust:
Building a Rust Native Module for React Native on iOS and Android.
But what about Flutter, Google's popular cross-platform developer tool? Let’s explore when it makes sense to use Rust with Flutter and what options are available.
When to Combine Flutter with Rust
- High-performance needs: Rust excels at writing performant, multi-threaded code, efficient algorithms, data-intensive operations, and SIMD code. If your Flutter app demands this level of performance, Rust is an excellent choice.
- A UI framework for Rust systems: Rust can be used to build powerful backends or data processing engines, and Flutter can serve as a UI layer for these systems.
- Using existing Rust libraries in Flutter: If the functionality you need exists as a Rust library but has no equivalent in Dart, Rust becomes a natural choice.
Options for Integration
To integrate Rust with Flutter, you need both the Flutter SDK and the Rust toolchain installed on your system. Two popular libraries make this integration possible:
Comparison of flutter_rust_bridge and rinf
Aspect | flutter_rust_bridge | rinf |
---|---|---|
Communication Mechanism | Uses code generation to create bindings, allowing Dart to call Rust functions directly. | Employs Protocol Buffers (protobuf) for message serialization, enabling structured data exchange. |
Asynchronous Support | Supports asynchronous Rust functions (async fn) for non-blocking operations. | Provides asynchronous communication mechanisms; specifics depend on the implementation. |
Data Type Handling | Automatically translates complex Rust types to Dart, simplifying data interchange. | Requires defining data structures in protobuf, which are shared between Dart and Rust. |
Setup Complexity | Quick setup with a single command to integrate into projects. | Simple setup without modifying sensitive build files; compiles out of the box. |
Getting Started with flutter_rust_bridge
Step 1: Create a Flutter Project
flutter create flutter_rust_sample
Step 2: Add flutter_rust_bridge to Your Project
Install the code generator:
cargo install flutter_rust_bridge_codegen
Integrate it into your Flutter project:
flutter_rust_bridge_codegen integrate
Step 3: Add a Rust Palindrome Checker
Navigate to the rust folder in your project, then add the palindrome
crate:
cargo add palindrome
Modify simple.rs
with the following Rust code:
#[flutter_rust_bridge::frb(sync)] // Synchronous mode for simplicity of the demo
pub fn is_palindrome(text: String) -> bool {
return palindrome::is_palindrome(text);
}
#[flutter_rust_bridge::frb(init)]
pub fn init_app() {
flutter_rust_bridge::setup_default_user_utils();
}
Step 4: Regenerate the Flutter-Rust Bridge Code
flutter_rust_bridge_codegen generate
Step 5: Update Dart Code
Modify the Dart code in your Flutter project to interact with Rust:
import 'package:flutter/material.dart';
import 'package:flutter_rust_sample/src/rust/api/simple.dart';
import 'package:flutter_rust_sample/src/rust/frb_generated.dart';
Future<void> main() async {
await RustLib.init();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('flutter_rust_bridge quickstart')),
body: Center(
child: Text(
'Action: Call Rust `isPalindrome("wow")`
Result: `${isPalindrome(text: "wow")}`'),
),
),
);
}
}
Step 6: Run Your Flutter App
Run your app with:
flutter run
Choose mobile or desktop, as these work out of the box. For the web, additional setup is required to enable WebAssembly (WASM). Stick to mobile or desktop for easier testing.
Conclusion
For this blog, I chose flutter_rust_bridge
to demonstrate how straightforward it is to set up an integration between Flutter and Rust. Compared to rinf
, flutter_rust_bridge
stands out for its simplicity and speed of setup. With just a few commands, you can have your project running, without needing to define Protocol Buffers or adjust complex configurations. On the other hand, rinf
provides a more structured approach, leveraging Protocol Buffers for communication, which might be preferred for projects requiring strict data schemas or cross-language compatibility.
As you can see, setting up an integration with flutter_rust_bridge
is a quick, 5-minute process. Once the basic setup is complete, you're equipped to extend your app with Rust's high-performance capabilities, whether for complex algorithms, handling data-intensive tasks, or integrating existing Rust libraries. While rinf
may suit specific use cases, flutter_rust_bridge
is an excellent choice for fast and seamless integration, especially for those new to combining Flutter and Rust.
Flutter and Rust together form a powerful combination, enabling you to build efficient, scalable, and cross-platform applications effortlessly. Whether you choose flutter_rust_bridge
or rinf
, this integration is an excellent way to take your app's performance to the next level.
Projects Combining Flutter and Rust
Here are some notable projects that showcase the integration of Flutter and Rust:
-
AppFlowy: An open-source alternative to Notion, AppFlowy utilizes Flutter for its user interface and Rust for its backend, providing users with full control over their data and customizations.
-
rhttp: This Flutter package employs Rust to handle HTTP requests, offering enhanced configurability and performance over Dart's default HTTP client.
-
RustDesk: A remote desktop application that leverages Rust for its core functionalities and Flutter for its user interface, aiming to be an open-source alternative to proprietary remote desktop software.
These projects exemplify the effective combination of Flutter's cross-platform capabilities with Rust's performance and safety features.