
How we use Rust in our mobile SDK - nfriedly
https://bionic.fullstory.com/rust-at-fullstory-part-2/
======
dpezely
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.

Perhaps it might help someone out there!

[1] [https://medium.com/visly/rust-on-
android-19f34a2fb43](https://medium.com/visly/rust-on-android-19f34a2fb43)

[2] [https://gitlab.com/dpezely/native-android-kotlin-
rust](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.)

~~~
tedmielczarek
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.

------
the_mitsuhiko
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.

~~~
therockhead
Is bitcode only required for watchOS and tvOS ?

~~~
tedmielczarek
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.

------
tmzt
From the article:

> 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?

[1] [https://github.com/stjepang/smol](https://github.com/stjepang/smol)

~~~
steveklabnik
smol was made public yesterday, so I would be very surprised if they
considered it.

------
mbalex99
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.

~~~
mmastrac
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".

~~~
vertak
You should give rust-embedded's `cross` project a look.

[https://github.com/rust-embedded/cross/](https://github.com/rust-
embedded/cross/)

I can't find any iOS related directories in their list of targets but there
are a couple issues related to supporting apple platforms.

~~~
tedmielczarek
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.

------
fulafel
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.

Rust issue about dealing with it: [https://github.com/rust-
lang/rust/issues/35968](https://github.com/rust-lang/rust/issues/35968)

~~~
anderspitman
Thanks! I've never developed for iOS and was wondering what that was about.

------
asymptotic
I successfully used Rust to create a shared library in a Flutter project that
works on both iOS and Android. So far I've only published the iOS app:
[https://apps.apple.com/us/app/ezmempass/id1490538369](https://apps.apple.com/us/app/ezmempass/id1490538369)

I heavily relied on the following blog post:
[https://dev.to/robertohuertasm/rust-once-and-share-it-
with-a...](https://dev.to/robertohuertasm/rust-once-and-share-it-with-android-
ios-and-flutter-286o)

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.

~~~
nmfisher
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).

[https://github.com/nmfisher/flutter_chinese_character_recogn...](https://github.com/nmfisher/flutter_chinese_character_recognition)

[https://github.com/nmfisher/hanzi_lookup](https://github.com/nmfisher/hanzi_lookup)
(forked from the original
[https://github.com/gugray/hanzi_lookup](https://github.com/gugray/hanzi_lookup))

------
hinkley
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?

~~~
hathawsh
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.

------
aazaa
From the previous article in the series:

> 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.

[https://bionic.fullstory.com/rust-at-fullstory-
part-1/](https://bionic.fullstory.com/rust-at-fullstory-part-1/)

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.

~~~
tedmielczarek
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...](https://bionic.fullstory.com/private-by-default-
mobile-analytics/)

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!

------
mundu_wa_hinya
Sad that you geoblock your blog

~~~
nfriedly
Try this link: [http://archive.is/B90AA](http://archive.is/B90AA)

------
jamil7
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.

------
PudgePacket
uMatrix blocks my browser from visiting this site...

~~~
saagarjha
Perhaps because they appear to be an analytics company.

~~~
Nextgrid
*spyware company

~~~
vmception
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

------
groobongithub
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.

~~~
azangru
I wouldn't mind reading about how Palantir uses Kubernetes :-)

------
rvz
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.

[0] [https://kotlinlang.org/docs/tutorials/native/apple-
framework...](https://kotlinlang.org/docs/tutorials/native/apple-
framework.html)

------
sergiotapia
>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.

How true is this?

~~~
mmastrac
> 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 didn't consider Nim in our language eval
([https://bionic.fullstory.com/rust-at-fullstory-
part-1/](https://bionic.fullstory.com/rust-at-fullstory-part-1/)), but you
could insert it into the scoring sheet to see how it might fare if we were
evaluating it ([https://language-compare.glitch.me/](https://language-
compare.glitch.me/)). I would be very interested in seeing the result.

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.

~~~
oconnor663
> [https://language-compare.glitch.me/](https://language-compare.glitch.me/)

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.

~~~
codesections
> 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.

~~~
maccam94
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).

[https://github.com/johnthagen/min-sized-
rust](https://github.com/johnthagen/min-sized-rust)

~~~
codesections
> 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)

