My experience at Rust Africa 2026 Hackathon
I got a random Whatsapp message from a friend late last year, also a Rustacean and ML Engineer. I opened it up to find a link to Rust Africa. I responded: “These hackathons are beginning to feel like bait. This one looks legit though”. Despite being on holiday and out of work, Rust Africa took up some space in my mind, where I passively ruminated over it. I knew I wanted to be a part, but the idea for the hackathon was fuzzy. I was at the Afcon finals part rooting for Senegal, fully rooting for Nigeria and part thinking about Rust.
The challenge of the Hackathon was to use Rust across these categories (Fintech & Inclusive Finance (Web3), AI & Developer Tools, Infrastructure & Connectivity, Climate & Sustainability, Embedded Systems & IoT), applied to problems native to the African space. The onus was on us to select a problem and a stack which checks all these boxes, and Rust as the core engine.
Problem to be Solved
The idea finally sprang forth. Habeeb worked on training a machine learning model (suited to local African languages) earlier , so he had an interest in Rust for ML inference as further work. I was open to the idea, so we hopped on a call with a third friend, Ope. The outcome of the call was to build an on-device file search application powered by Rust a.k.a Achø. The two main features were traditional keyword matching (with the BM25 algorithm), and semantic search powered by a machine learning model.
Choice of framework
Web or Mobile?
We opted for mobile because it’s the better medium to deploy a file-search application. After sufficient permissions are provided, available PDF files on a device are scanned without repeated actions from the user. On the other hand, the web will require uploads, which defeats the purpose of the application.
Tauri, Leptos, or Dioxus?
Leptos being exclusively for the web excludes it. Neither Dioxus nor Tauri currently offers FileSystem API by default. We need FileSystem APIs for File search. Ope tried out a few hacks with Tauri, using plugins here, but this didn’t work.
https://github.com/DioxusLabs/dioxus/issues/3855
https://v2.tauri.app/plugin/file-system/
This led to our first design decision to step out of Rust. No framework in Rust provides low-level access to filesystem APIs . Given my experience with Flutter on previous projects, I had initially suggested Flutter as a fail-safe, in case none of the frameworks in the Rust ecosystem suits our peculiar needs. The core engine would still be powered by Rust.
We pivoted to Flutter to build the mobile application in order to access a user’s filesystem. After which, files can then be scanned, indexed and/or embedded. At this stage, I built out a minimal U.I for the search app, and wrote a native Dart function which scans all the pdfs on a device. We tested that. It works. Blocker resolved.
FileSystem API resolved, now add Search
The next set of actions was:
- Implement the keyword search feature (powered by the BM25 keyword matching algorithm).
- Enable semantic search with an embedded machine learning model.
- Integrate Rust-powered functionalities to Flutter.
Since Habeeb worked on training the ML model (suited particularly to local languages), he worked on the inference of the machine learning model with Rust.
I worked on implementing the keyword search feature and integrating Rust-powered functionalities to Flutter. I hit a couple of blockers:
- Implementing the keyword search feature, there was the option to implement from scratch or use existing libraries. I opted for the latter, filtered down to SeekStorm and Tantivy, but chose SeekStorm due to its superior speed.
- In powering Flutter with Rust, you either build on the great work done with flutter_rust_bridge library , or export a plain C ABI from Rust, write your own ffi layer with dart:ffi. I opted for the former option, but I soon discovered I would be unable to compile SeekStorm through flutter_rust_bridge for mobile targets due to the use of crates such as gxhash incompatible with cpu architecture for mobile (requiring aes2, sse). Another quick pivot back to Tantivy. Tantivy does not use gxhash, but ahash. Ahash was able to compile for mobile. Win!. Associated keyword search functions were ported to flutter with Rust being the core engine. Days of being blocked summarized succinctly.
Next, Integrate machine learning model
One of the challenges around this, perhaps due to the nature of flutter_rust_bridge. Compiling multiple crates led to initialization errors on the dart side. One crate was initialized while the other was not (https://github.com/fzyzcjy/flutter_rust_bridge/issues/2972). In this case, I resolved the issue by bundling both crates as one, instead of multiple crates.
Another challenge was the issue with flutter_rust_bridge automatically compiling for i686-Android, Android-x86 targets (of which some dependencies e.g the ort crate were unavailable). The solution to this was to manually edit some flutter_bridge_rust source code to only include the Android arm64 target. This is an issue with a dependency of flutter_rust_bridge, cargokit.
During the process of bundling the application, there were issues to iron out regarding ndk compatibility with Ort crates. I ended up building to Android ndk 27(stable version on Onnx runtime).
What we didn’t have enough time for
- Optimization of Android build, catering to the resultant effect of tree-shaking in the process of bundling an application.
- Optimization of ML model inference on the Dart side.
Takeaways
- The time spent selecting the right tool for the job is just as important as the time spent getting the job done.
- Communication across the team on blockers is always very helpful.
- You can’t always foresee all blockers; sometimes, build even when it’s foggy, clarity usually comes after.
- Along the lines of what I’d do differently if I started this all over again, that answer depends. My goal for this hackathon was to use it as an avenue to write more Rust outside of my day job, which turned out to provide me the opportunity to do more ML inference in Rust, and even power Flutter with Rust. Doing it again, the goal probably changes :)
- Lessons learnt here in terms of project management are minimal since we were our own stakeholders, we had no scope creep, communication was fluid, the timeline changed by a day but we got it over the line.
Links
github repo: https://github.com/HAKSOAT/acho
slides:https://docs.google.com/presentation/d/16ACQ_ywqtdFuwI_hMWJXQe9s4m_zFCm1tyl-ONQmeUg/edit?usp=sharing