For others considering Rust + Kotlin for native Android development, there's also the Visly blog post[1] with basic steps. However, since then, Google officially released `androidx`. Unfortunately, Android Studio or the SDK lack `cargo fix` features of modifying your source code and instead just magically compiles with a compatibility layer. There's a PR on Visly's GitHub repo with these code fixes.
Also, their code base is minimal: does just enough with Rust shared library to have an app generate a log message. That's enough if you already know Android development.
For a complete end-to-end example search query screen with results screen (Activity, Fragment) using Rust, Kotlin, androidx, RecyclerView, ViewModel, etc., there's [2], but it was written while learning all things Android.
Edit: Yes, that second one is mine. Had fun learning but hopefully will never have to touch mobile dev again beyond maybe a PWA. (I'm a server-side dev.)
I think the build system side is still a bit rough around the edges. It's not hard to get something working, as your examples show, but I haven't seen a solution that feels really well-integrated yet. I'm hoping that tools like bazel/buck/pants continue to get more useful and can provide that kind of experience.
This is really interesting to see. For us (Sentry) we did not dare yet to put rust code onto the client largely because people really want bitcode support and that has been a challenge with an open source SDK because of the custom rust compiler requirements.
(Hi!) I agree the bitcode situation with Rust is painful. Our SDK isn't open source so we're able to sidestep a lot of that pain but we still do have to be mindful of interop issues with the LLVM version we use to build our SDK and the XCode version our customers use to build their apps. It would be nice if Apple and LLVM committed to some bitcode stability guarantees that would make a this easier to handle.
I believe so, yes, but we have customers that wanted to ship their apps as bitcode (for reasons I'm not aware of) so we need to include bitcode in our framework to support that.
> Because our code winds up running in other people’s apps we don’t use a full-fledged async runtime like tokio or async-rs since those are optimized for “use all available resources” scenarios like network servers or client applications.
Have you considered the recent alternative, smol [1]?
Do you have any plans to share source or build scripts for the glue components?
How have you been able to incorporate native functionality such as media codecs and screen capture with shared logic written in Rust?
Has Rust worked well when you also need to integrate with runtimes such as React Native or Flutter?
> Have you considered the recent alternative, smol [1]?
I've been reading Stjepan's articles and am very interested in what he's doing but we haven't seriously looked into alternatives yet. He reached out to me after this post went live and I've promised to follow up!
> Do you have any plans to share source or build scripts for the glue components?
We'd like to open source bits of our work that are separable and useful to others but often glue code and build scripts fall way short of that because they're very much tied into our specific arrangement. I'm not sure there's much there that's novel in any event, it's mostly just using the set of crates I list in the post in the standard ways.
> How have you been able to incorporate native functionality such as media codecs and screen capture with shared logic written in Rust?
We don't handle video currently AIUI so we haven't had to deal with codecs. We primarily try to put platform-specific integration code in the platform-native part of the codebase, which is ObjC for iOS and Java for Android, and transform things down to a more straightforward form like byte buffers to hand off to Rust.
> Has Rust worked well when you also need to integrate with runtimes such as React Native or Flutter?
We have some React Native support and it hasn't been any worse than supporting the other toolkits we support. I don't think we have Flutter support in a place where I could speak usefully about it.
Thank you for the Ditto shoutout! Our team took quite some time to make bitcode and rust work with our customers. Glad to see it was useful for another company building cross platform SDKs.
Thank you for making that available! I understand why it's hard for upstream Rust to provide and I hope they'll find a solution eventually but until then not having to reinvent that wheel saved us a lot of time!
Big thank you for making those public. It saved us a bunch of time. We'd like to figure out how to make this easier for people - possibly by providing a binary cross-platform toolchain that "just works".
I don't think this really solves any problems for us unfortunately. The core of the bitcode problem is that you need the rustc you're using to have the exact same version of LLVM as the Xcode toolchain you're using, since bitcode is a not-entirely-stable internal LLVM format. Cross-compiling to most mobile platforms is actually pretty straightforward with Rust.
For anyone else wondering about the fixation on LLVM bitcode: It seems that Apple in some cases requires app app store uploads in a certain LLVM version's bitcode format (their Xcode is based on LLVM), instead of binaries, so they can do transformations to it before sending out to users.
Overall it's painful to set up and requires knowledge of the native platform (XCode/Swift, Android Studio/NDK/Kotlin), but overall it works and it was fun getting it working.
I'm happy to answer more questions about it, I've been meaning to write up the experience and details.
I recently did something similar (though I haven't had a chance to clean up or document the repositories for Flutter plugin/Rust library yet).
The Flutter application uses FFI to invoke the Rust library, passing a series of strokes (i.e. coordinates on a 2D canvas) and returning a list of Chinese character candidates.
Although it's not yet stable, I was very impressed with Dart FFI. I've used both JNI and .NET PInvoke for native interop before, and Dart FFI was probably the easiest (PInvoke is fine, but JNI is horrible).
A bad pattern I’ve been trying to sort out for myself lately is that I pick projects that sound like I would be good at and that could be interesting instead of picking projects that look like ones I actually feel nostalgia for.
It’s like I’m always chasing after the Bad Boys or something.
Two of the biggest nostalgia experiences have been embedded or mobile projects. I got out when it became clear that the people who run the credit cards make all the money and treat you like a mushroom (keep you in the dark and feed you bullshit). I told a friend at the time that AT&T is a racket for converting VC dollars into free QA.
Objectively, how are things in mobile now? Should I have ended my self-imposed exile ages ago? Are they just desktop apps with limited pixels, or is there still skill involved with squeezing things into small spaces?
I had a simple Radio Shack RC car when I was young. When it started to wear out, I took it apart, hoping I would be able to improve it. It turned out to be nearly pure analog circuitry, and I didn't know where to learn more about analog circuits, so that was the end of that.
When I grew up, I got my kids similar cheap RC cars, but when they broke, this time I replaced their circuitry with ESP8266 D1 minis with the D1 motor shield. I 3D printed new shells, added lights, and used PWM frequency variation to play music through the motor windings. I made a simple app that controls the cars over wi-fi. My kids loved them much more than the original.
It didn't take much effort because the tools are all much easier to use today, but I'm rather proud of my little accomplishment. I turned a mildly sad childhood event into something really fun for my kids. I turned the nostalgia up to 11. ;-)
So if you're looking for some way to do something nostalgic and fun, find a way to make something you've always wanted to make, then give it away. The project isn't really complete until someone else enjoys it.
Mobile development still has some unfortunate features, like Apple's App Store guidelines limiting the types of apps you're allowed to distribute there, and ever-changing requirements that mean that apps that don't get updated for newer OS releases (even if the app is otherwise fine) get removed from the app store.
Even with that, mobile is where all the users are nowadays. Traditional desktop/laptop computing is not a growth market. If you want to build software that lots of people will use you want to build it for mobile platforms. Smartphones are also ridiculously overpowered at this point, so you do have the resources to make pretty compelling experiences unlike with what you'd think of as a traditional embedded system.
I too am nostalgic for the early days of mobile when system resources and screen size were both scarce. It required creative solutions. It was fun. Nowadays with larger screens and phones that are as fast as your laptop, mobile apps share more in common with desktop apps than not.
> Our problem is further complicated by the fact that we’re not shipping an app but a framework for others to use in their own apps. We have to be mindful of the impact our technology choices have on our customers, such as the potential for harmful interactions with their code, and user-visible performance impact in terms of CPU and memory usage.
Without knowing the details, framework-as-a-product argues strongly for a native-only approach to me. Xcode + ObjC/Swift on iOS and Java on Android.
The article(s) might make a better case for polyglot by talking in detail about what the framework does in more detail. The bar for going in that direction would be very high for me.
Thanks for the feedback! You're right that describing our usage a bit better might have helped clarify our thinking. For the record: the FullStory product is a session record and replay tool for both web and mobile. We record details about how your users interact with your site or app and you can watch replays of them as well as get analytics across sessions. Privacy is important to us, which you can read about here: https://bionic.fullstory.com/private-by-default-mobile-analy...
The bulk of what we're doing in Rust is data serialization, along with business logic, part of which is a state machine and part of which is applying specific rules to app content. We did have fully native implementations of this in our prototype. Supporting two parallel implementations would be way harder for us than supporting our Rust implementation. It's hard enough to support the code that's platform-specific by necessity!
I looked briefly into this before starting to port a Swift app to Android. I ended up rewriting all my business logic and I/O in Kotlin Native and found it to be a really great solution. I'm not sure why it isn't more popular to be honest.
I was working at a startup in 2016 that was using FullStory.
We routinely pointed out how the Netflix documentary in 2025 was going to be a conspiracy style one with eerie music. But in the mean time lets flip shares to VC's and larger corporations as fast as possible and move to the Marina like nothing happened
Knowing what the Fullstory product is I'm a bit un-interested in what they're doing with cool new technologies.
This is a bit like reading how palantir is using Kubernetes.
Great. Now you have 3 separate languages to maintain. Make that 4 if you're using Flutter or React Native.
You could use Kotlin Native [0] to eliminate the tertiary language (Rust) which essentially boils to 2 languages used if your Android app is written in Kotlin and you can then use your business logic as a dynamic library for iOS to link against as a cross-platform SDK.
>Overall we feel like the core value propositions that Rust promises (Performance, Reliability, Productivity) have proven true at FullStory. We’re able to write performant code without spending excessive time in optimization.
Sounds like they could have had the same things with a much easier language like Nim. Unless they are using a lot of Rust exclusive features?
>We can confidently make sweeping changes to our codebase, and trust that the Rust compiler will point out anything that isn’t correct.
I will also caveat that we are building code that ships in other company's apps, so our requirements will be different from others.
> How true is this?
Ballparking some of our internal issue counts here, so please forgive major rounding.
Out of all the crasher bugs on our team (our most serious category obviously), none have been in the Rust code itself. In a handful of cases Rust has caused the platform glue to crash via timing issues (shutting down platform glue in the wrong order/bad assumptions).
Out of all the general bugs (fidelity, wedging, performance, etc), ~90%ish are in our platform glue code -- ObjC/Android -- and the remainder of Rust bugs are again mostly timing/bad assumptions in async code.
It's been really amazing how confident Rust has made us. Code that compiles generally works.
Putting numbers to things like this is a fuzzy business of course, but I'd be interested in comparing notes on some of them:
- I'm surprised Go gets a 1.0 for thread safety, while Java only gets a 0.5. My understanding is that, at the lowest level, producing e.g. a torn pointer is not possible in the Java memory model, while it is possible in Go.
- I think C++ deserves at least a point or two over C for thread safety, for the same reason it gets a couple points for memory safety. The distinction between raw pointers and smart pointers makes it a lot clearer who is supposed to be owning what, and seeing shared_ptr in the code can be a good reminder that something is likely to race.
- Is Rust really harder to learn than C++? :) I'd normally give C++ a lot of points for familiarity, but that's already split into a separate row.
> - I'm surprised Go gets a 1.0 for thread safety, while Java only gets a 0.5. My understanding is that, at the lowest level, producing e.g. a torn pointer is not possible in the Java memory model, while it is possible in Go.
Some of the original reasoning behind the numbers is swapped out, but much of this scoring was that we were burnt so much by the ease of passing objects between threads and accidentally racing that we dinged Java. Our company's experience with Go has just been better, but Go also has first-class goroutines that mostly enforce doing stuff "right", and had better tooling around multithreaded race detection [1] especially at the time.
> - I think C++ deserves at least a point or two over C for thread safety, for the same reason it gets a couple points for memory safety. The distinction between raw pointers and smart pointers makes it a lot clearer who is supposed to be owning what, and seeing shared_ptr in the code can be a good reminder that something is likely to race.
That's a good point. We might have scored it somewhat differently if we were more familiar with C++ at the time but most of our C++ knowledge on the team was pretty old, and especially sparse around multi-threading.
> - Is Rust really harder to learn than C++? :) I'd normally give C++ a lot of points for familiarity, but that's already split into a separate row.
IIRC, the rationale was that C++ is mostly familiar concepts that senior developers have encountered in some form, while Rust introduces brand new concepts that we just don't have a good reference point for.
This is absolutely fuzzy business, and a different team will have different weights/scores than us!
> Putting numbers to things like this is a fuzzy business of course, but I'd be interested in comparing notes on some of them.
Me too. I'm especially surprised that Rust gets a 1.0 for size ("What’s the size impact of this language on the framework we would deliver for our customers?"). For comparison, C also got a 1.0 and Go got a 0.3. I _far_ prefer working in Rust to working in either Go or C, but my experience hasn't been that Rust binaries are anywhere near as small as equivalent C ones.
Have you tried making them small? Rust doesn't optimize programs for size by default, there's a lot of easy ways to shrink binaries (like stripping symbols).
> Have you tried making them small? Rust doesn't optimize programs for size by default, there's a lot of easy ways to shrink binaries (like stripping symbols).
Yeah, I have. I'd come across the guide you linked, any frequently use the subset of those techniques that are available on stable Rust. And I've ended up with simple CLI apps in the 2 to 4 MiB range – which is _fine_ for my use-case, but a bit closer to the size of a Go binary than a C one. (Though, like I said, it's fine for my use case and, if it were important to me, I'm sure I could trim that a bit by picking different dependencies or even dropping to `no_std` in some cases)
I'd like to know more about what you found lacking in Kotlin/Native. That would seem to be the lowest-friction option, since Kotlin targets the JVM on Android and Kotlin/Native directly supports interop with Swift.
Kotlin did pretty well in the matrix [1], though it appeared to be weaker in the areas of memory control and thread safety. These two areas stood out as important because we were bit by them over and over when we had two parallel native codebases written in Java + Objective C.
Not crashing our customer applications, and not exposing them to any additional security vulnerabilities is top priority.
It's important to keep in mind that we evaluated these options 18 months ago (roughly), so numbers might have changed.
Note that we specifically do not use Swift at this time -- even in our platform glue -- because we cannot guarantee that a Swift runtime appears on all devices that we are targeting. We are evaluating options to allow us to use Swift in our glue.
I'm a little surprised that Go gets the same score for thread safety as Rust, since safe Rust guarantees a lack of data races, and as far as I know, they can only be caught at runtime in Go. Is there some reason that data races aren't a concern for this project?
> Sounds like they could have had the same things with a much easier language like Nim. Unless they are using a lot of Rust exclusive features?
I admit that I don't have more than a passing familiarity with Nim. Rust certainly isn't the only language targeting this niche nowadays, but it has done a lot of things right and we're not the only ones using it. There's no perfect language, they all have positives and negatives. Rust is still new enough that the ease of hiring developers can be a negative, so choosing an even younger language would further exacerbate that problem. Rust also has enough usage these days that we can get a lot of things from crates.io without having to write them ourselves. I don't know how Nim compares but it's pretty hard to get there without having enough adoption. Finally, Rust has had a bit of a trial by fire in terms of making it usable for integrating into existing codebases and shipping production code to users. I was at Mozilla and helped lead part of the Firefox Quantum work to integrate Rust into Firefox. We ran into a number of issues that we surfaced with the Rust team. Those issues generally were fixed in upstream Rust so everyone using Rust benefited from that work. I don't think that's too high of a bar for other languages to clear but it's a lot easier to recommend Rust knowing it has been through that already.
> How true is this?
I joined FullStory in December and some of my first changes to the codebase were large refactors, well before I understood how everything worked. None of them caused any major regressions that I'm aware of. My experience over 5 years of using Rust is that if you make the compiler happy you are pretty likely to have working code.
> I admit that I don't have more than a passing familiarity with Nim. Rust certainly isn't the only language targeting this niche nowadays
Don't let the Nim folks fool you. Nim isn't targeting the same space as Rust. It's garbage collected.
Nim could see success in challenging Python or Golang, but Rust is rather uniquely positioned to go after bare metal (C, C++), yet have the ergonomics one would expect from Java, Python, Go, etc.
Just pattern matching and destructuring being in the language from 1.0 makes Rust a much different beast ergonomics wise than Java, Python and Go. It makes it different than Scala even, as it feels more cohesive to me.
There are many things that could be done to make Rust easier at the cost of bare metal semantics, which is why they aren't done, but I am quite happy with the current state of the language and even with those tradeoffs I agree that Rust has great chances of "taking over" a wide range of spaces that are currently dominated by specific technologies.
Rust absolutely does not have the ergonomics of any of those languages because it has lifetimes. They are things you don't worry about in those languages.
Have you done a lot of Rust? I spent considerable time in Rust, and at the end of the day, after stepping away from it, I've found multiple options with the kind of ergonomics that make development a lot more productive for me.
Rust is not going to eat everything. I'd bet money on it. Rust will likely un quietly behind the scenes powering lots of great projects, but its audience is limited. I think HN really has a weak spot for understanding how few people even know what it is. I was surprised to ask a CS grad student that's done lots of machine learning about Rust, and he simply didn't know it existed. I like Rust and all that it taught me, but we need to be realistic about its ceiling and what it is appropriate for.
> Rust absolutely does not have the ergonomics of any of those languages because it has lifetimes. They are things you don't worry about in those languages.
You have to worry about them in any non-garbage collected language. There's just no compiler that checks that you're doing it correctly and is the primary source of security bugs for most software.
Understood. To be specific, they said Rust has the ergonomics of Python, Go, and Java, which are garbage collected languages. It does not strike me as realistic.
I don't see how can Rust be more ergonomic than Python, can you elaborate? A data scientist doing some analysis is not concerned with memory safety, why will he waste his time fighting the compiler?
I don't think there's a bright line dividing systems programming problems between GC and non-GC languages. We use Go extensively at FullStory and it works great for a large class of problems. Rust has a compelling story for spaces where GC makes life harder or just isn't feasible. I will say that Rust being usable without GC does seem to put it in a better position around interoperability than languages with a GC, since composing language runtimes and GCs properly is a really challenging problem.
Rust does quite a lot of checks at compile time. It does the obvious ones like type checking (check out the static_assertions library[1]), but it also ensures that there are no race conditions between threads and other memory-safety things like that.
I know this gets repeated to the point of being a meme, but I think it's worth being precise about this; Rust guarantees that there are no data races (i.e. accessing memory in one thread while it's being written to in another), but there can still be other types of race conditions (e.g. non-determinism based on which of two threads finishes a given task first).
Is Nim a viable alternative to Rust? Didn't it just release 1.0? Their production users list[1] doesn't look very impressive. The size of ecosystem matters a lot.
chicken and egg problem. Nim is a viable alternative to Rust, Python programmers feel right at home, compiles to C, and you can use any C library out there.
Nim's performance is also ridiculously fast and low memory.
Not to advocate for one language over another, but sergio, you're right, Nim is ridiculously underrated and a much easier to use than rust. There's just a lot less mental overhead in almost anything and iteration is going to be much faster because lifetimes do get in the way.
Unfortunately this is one of those things where hype has kind of won out and I think a lot of people are dismissing an option like Nim simply because we're not talking about it on places like HN. Though, to be fair to Rust, the community is doing a lot of bleeding edge stuff that Nim's community just isn't big enough to.
I think like so many things we tend to turn programming language discussions into something akin to discussing religion. I really like Rust but that doesn't have to take anything away from other languages. I'll have to take a look at Nim at some point, it sounds like it has a lot of nice qualities! I really love that we're in what feels like an explosion of new and exciting languages to work with. I don't think Rust is the pinnacle of language design, so having more languages explore the space of possibilities is great!
With all that being said, when it comes to choosing a language for use in a business context the popularity of the language absolutely does matter. It has an impact on your ability to hire programmers, find packages to solve the problems you have in the language ecosystem, and have tooling that meets your needs, just to name a few. Now there is definitely a chicken-and-egg problem here as someone mentioned in another comment, in that you need adoption to drive adoption.
I'd advise you to try not to take these things personally. If you love Nim focus on doing cool things with Nim and making the Nim community a great place to be.
Yes and no; there are areas of differentiation between different statically typed languages. For example, Rust has one of the strongest abilities to prevent concurrency/parallelism errors via its type system, but is also missing some other things, like dependent types or higher kinded types.
Also, their code base is minimal: does just enough with Rust shared library to have an app generate a log message. That's enough if you already know Android development.
For a complete end-to-end example search query screen with results screen (Activity, Fragment) using Rust, Kotlin, androidx, RecyclerView, ViewModel, etc., there's [2], but it was written while learning all things Android.
Perhaps it might help someone out there!
[1] https://medium.com/visly/rust-on-android-19f34a2fb43
[2] https://gitlab.com/dpezely/native-android-kotlin-rust
Edit: Yes, that second one is mine. Had fun learning but hopefully will never have to touch mobile dev again beyond maybe a PWA. (I'm a server-side dev.)