Skip to content

The Story of Rustroid (and also me, I guess)

If you don't already know, Rustroid is a Rust IDE for Android that runs locally on the device.

It All Began with Minecraft

Back in my past, I was a 12-year-old watching YouTubers play on Minecraft Java Edition servers with mods. The mods were awesome and mind-blowing, and I wanted to try them.
One mod that I wanted to try so much was the Morph mod. It is a mod that allows you to become any creature that you kill.

But I didn't have a PC or even Minecraft Java. All I had was a mobile phone with Minecraft Bedrock Edition, which didn't have any amazing mods. So, I decided to try to create a mod myself for the mobile edition. I didn't know what to do or where to start. I just downloaded a bunch of mods and tried to open their files to understand how they worked.

That was the moment I realized that the Android ecosystem lacked any kind of developer tools.

Back then, all the mods for Bedrock were just JSON files. I wanted a JSON editor, and all I could find was an application named QuickEdit. It wasn't very advanced, but it had useful features like syntax highlighting, undo/redo, and search/replace. However, it lacked a linter, autocompletion, diagnostics, or any of the features that make programmers happy.

In the end, I started copying and pasting some parts from here and there and created the most advanced Morph mod for Bedrock Edition at the time, using only my mobile phone.

And then i deleted the mod and moved on to other things, but that's not the point of this article. 😃

Moving on from Minecraft

After what I would call a huge success, I wanted to move on and do other things. I wanted to do more.

I started experimenting with the Java language because I wanted to know how to make a game that could compete with Minecraft (which, by the way, was a silly idea), again all from my Android phone. I started watching a really good tutorial by RyiSnow on creating a 2D top-down adventure game Playlist link.

The tutorial explained how to create a 2D game using Java swing/awt graphics. And, as you may know, Android is built on top of Java, so everything should work, right?

Well, no. It turns out that Android does not include the full Java. It only includes parts of it, and Java swing/awt is not included. But Android does have an alternative. Android apps consist of Activity which is the entry point of the app.

and View which is like the alternative to JComponent, and views does contain an onDraw(Canvas) method that is responsible for drawing stuff on the screen It's very similar to java's JComponent.paintComponent(Graphics). So, I began to follow the tutorial, but I replaced anything Swing related with the Android alternative.

Oh, right, I didn't say how I was able to follow the tutorial without an IDE, a Java compiler, or even an Android APK generator. Well, there was a new application in town called CodeAssist. It allowed the user to build Android applications with Java. (Btw, it's not maintained anymore, and it was, and still is, in beta or even alpha, I don't know.) I ported a large amount of the game and was genuinely happy.

The Small Beginning

I wanted to create an IDE for Java using CodeAssist. I know, very original. But you always want to replicate the tools you use. I tried using CodeAssist to create it, and I would say I got somewhere. I got familiar with the Android SDK and how APK generation, the Java compiler, and other things work.

But again, that's not what this article is about.

The Real Beginning

I finally got my hands on a PC. I tried Rust to see why there was so much hype about it, and yeah, I kind of liked its ecosystem. You know, all things in one: the compiler, the package manager, the test suite, the docs. they are all one and the same (named cargo).

I installed Android Studio, created a new project, and literally dumped everything else that I had created. I called the project Rustroid.

You may ask why I created a Rust IDE and not a Java one. Well, there were three reasons (Or maybe more, I don't know, LOL).

  1. I discovered that Rust is the most admired language.
  2. There was a very good IDE for Android that was currently being worked on, called AndroidIDE. (AndroidIDE is also unmaintained now. 😕)
  3. I just loved the language.

When I was creating the project, I set the language to Java and was going to make the app with the views-based approach, like I used to on my phone. But I wanted to try Kotlin with Jetpack Compose because Kotlin and Jetpack Compose were Android Studio's recommended defaults for new projects. And oh boy, I fell in love with Kotlin and Jetpack Compose. I didn't go back to Java after that.

How Does Rustroid Work?

To understand how Rustroid works, you first have to understand how Android works. Android is an operating system based on Linux, which means it shares the same internals as a fully featured Linux distro. And Android supports Java, which itself supports Process and the ability to execute native processes. So it should be possible to run Rust on Android. I just needed to grab the Rust version that is compiled for aarch64-linux (My phone's architecture) and execute it on Android, and it should work, right?

Well, no. It turns out that there is a fundamental difference between regular Linux distro binaries and Android binaries. Linux binaries are linked against gnu's libc, while Android is linked against bionic's libc.

The Implementation

I figured out that there are a bunch of folks who are porting almost every Linux package to Android. How? Well, they are compiling it with the Android NDK, which links them with bionic's libc. These folks are the guys behind Termux (a terminal emulator for Android). So, I copied their compiled Rust with its dependencies, patched some parts of it, and boom, it works.

Note

When I mentioned the people behind Termux, I was referring to the Termux-Packages project. The packages they compile are licensed under the same license as the original package, so their Rust package, for instance, is licensed under either Apache 2.0 or the MIT license. You can also find all the license information in the about screen of my app. When i said the guys behind Termux i was referring to . And the packages that they compile are licened under the same license as the original package. (So their rust is licened under APACHE2/MIT).
And also you can find all the licenes inside the about screen of my app.

Now, what does an IDE need?

  1. A powerful code editor (with LSP)
  2. A terminal emulator
  3. A file explorer and a good interface

The third was the easiest and not very difficult, I would say.

The Code Editor

I wanted to implement the code editor with at least the following features:

  • A fast and memory-efficient text buffer.
  • An undo and redo manager.
  • Syntax highlighting using TextMate.
  • LSP integration.

The Text Buffer

At first, I wrote it using an array of lines, but the performance wasn't that great, and it had several disadvantages. But then, my eyes caught this article from VS Code: VS Code Text Buffer Reimplementation. It's a great article; I recommend you give it a shot. From the VS Code's article:

The mental model for an editor is line-based. Developers read and write source code line by line, compilers provide line/column-based diagnostics, stack traces contain line numbers, tokenization engines run line by line, etc. Although simple, the text buffer implementation powering VS Code hadn't changed much since the first day we kicked off the Monaco project. We used an array of lines.

However, we kept receiving reports that opening certain files would cause Out-Of-Memory crashes in VS Code. For example, one user failed to open a 35 MB file. The root cause was that the file had too many lines, 13.7 million. We would create a ModelLine object for each line, and every object used around 40-60 bytes, so the line array used around 600MB of memory to store the document. That's roughly 20 times the initial file size!

Another problem with the line array representation was the speed of opening a file. To construct the array of lines, we had to split the content by line breaks, such that we would get a string object per line. The split itself hurts performance, which you'll see in benchmarks further down.

I know that this shouldn't even be a problem for my app, as no one would open such big files on their smartphone, right? Well, yes! But I implemented the piece tree buffer anyway. 😉

It took some days, but it was working, and I ported the VS Code piece tree text buffer tests to Kotlin. And all of them passed.

By the way, I don't write tests for my code. I either stea... I mean, copy them, or just leave the code without tests.


The Undo & Redo Manager

Well, that wasn't hard. Just create a list of an Action class that has an undo and redo method, and create an index variable. Insert/delete the text based on whether we are undoing or redoing. When undoing, decrease the index, and when redoing, increase the index. And that's it.


The Syntax Highlighting

Well, I just ported the VS Code implementation of TextMate to Kotlin and used it. By the way, porting Microsoft's code is not that easy; just because I said I just ported it doesn't mean it's easy. I think they are trying to make the code more complicated than needed on purpose. So, yeah.


the LSP (The Fundamental Part of the IDE)

The LSP stands for Language Server Protocol.
It's a protocol that allows a client to communicate with a server to get information about everything related to a specific programming language.

The first thing to do was to read the LSP spec.

The brief of the protocol is that the IDE (the client) and the language server communicate through std in & out or TCP, or Unix sockets, or whatever, and it's based on JSON-RPC.

The base protocol consists of a header and a content part (comparable to HTTP).
The header and content part are separated by a \r\n.
The header part contains the Content-Length, which specifies how long the content is. This is needed to be able to know when the message ends.
The content part uses JSON-RPC to describe requests, responses, and notifications.

Thanks to Kotlin sealed classes and kotlinx.serialization, implementing the LSP wasn't very hard. And that's it: the client and the server send a bunch of requests/responses to each other, and boom, everything works!


The Terminal

I took the terminal emulation part from Jackpal's Android Terminal Emulator, converted it to Kotlin, converted it to Jetpack Compose code instead of Android-specific code, and fixed some bugs, you know, things like that.

Other Things

You know, there are other things to take into consideration: the code editor needs to measure text and render text, handle scrolling, update cursor position, and make sure that the cursor is not in the middle of a surrogate pair.

Note

Java does not use UTF-8 it used UTF-16, so some characters (e.g., emojis) have two codepoints instead of one.

Creating hover, signature help, completion, diagnostics popups, go-to-definition, declaration, implementation, etc.
Implementing a code snippet parser (because the LSP may send snippets)
Implementing a fuzzy sorting algorithm for sorting completion items (because they are not sorted by default)
and of course, The APK generator, which compiles your code into a shared library and then zips it, zip-aligns it, signs it, and many other things to take into consideration.

Publishing the app

At first, I wanted to make it open source and publish it on Google Play so I could get contributors from all around the world and, at the same time, make it available to almost all Android users.

In fact, early on, I did actually publish the source code on GitLab for about 3 days or so. But then I deleted it.

Why not open source

As you can see, both CodeAssist and AndroidIDE are not maintained anymore. I think this is due to a lack of funding, which completely removes the motivation for continuing to develop them. Sure, there are donations that come once in a while, but that's not enough to make someone continue working on a project, especially if he has no job and no other source of income (like me). Maybe, just maybe, in the future, I will reconsider making it open source to benefit the community and even myself.

Closed source distribution

Now there are four options to distribute the app.

  1. Distributing it for free without ads.
  2. Distributing it for free with ads.
  3. Distributing it for free with limited features and offering in-app purchases to unlock the app's full potential.
  4. Distributing it with a one-time purchase.

I can't choose number one, as that would make me broke 😃.
For real, though, if you would make it free, then just make it open source.

And I can't choose number two either. I don't like the idea of ads; they are just really annoying, and I just don't like them.

Now it's all about number three and four. Number three is not that bad.
But I don't like it that much; I prefer to distribute the app with it's full potential, for anyone who can obtain it.

So that leaves only number four: making it paid.
And yeah, that's what I did, but I don't think that it's expensive, though. (And I plan to keep it that way.) That's because the app does target those who don't have computers, so I don't think that it's fair to make it expensive.

The app's price is $7.00 USD.

If you are in a country that does not support Google Play purchases (ex. Syria), or you just don't have enough money, Contact me and I will try to give it for you for free, In sha Allah.

The End

I know that i haven't said a lot; I am really too lazy to write. Man, I do hate writing.

Creating this IDE allowed me to learn a lot, and I mean a lot. I am too lazy to write what I learned, but I mean it.
This article is only a brief of how Rustroid works, and coding the app took more than a year. It could have taken less time, but I was just learning new stuff.

Now I am in the last year of high school (I'm 17, by the way). I hope to find time to keep working on the app this year (by this year, I mean 2026 😉).

Btw, I did convert the IDE to Compose Multiplatform so that I can run it on my PC without having to connect an Android phone (To make the development of it easier.). Also, I do plan to create an IDE for every language out there (In sha Allah) since I implemented the foundation of the IDE, so stay tuned!

You can download the app from Google Play, via this link.

Best regards,
MohammedKHC

Oh, right, that's not an email. Ignore the last part. LOL.

Last updated:

Made by MohammedKHC.