The Time Has Come
Over the past few years, pure Linux-powered mobile devices have found their way into the mainstream. The ability to run a customized kernel on something like an Android device is nothing new, and the same can be said for iPhone jail-breaking.
The difference here is that these devices (many of them at least) are built from the ground up with a focus on free and open-source technologies. As such, they aim to run fully open Linux-based operating systems, and in many cases include physical hardware switches to disable various components to provide additional user privacy.
The rise of more powerful and inexpensive ARM-based chips now mean that many of the devices have the potential to function at levels equivalent or close to mid-range closed source devices running iOS or Android.
Many hobbyists and developers (such as myself) have started flocking to obtain these devices, leaving many of us with the same question after getting one: “This is awesome, but how do I go about creating my own apps for this thing?”. My hope is that this article will help some of you answer this question, and assist in developing your own applications for these popular devices!
One of the most popular Tux phones on the market is without a doubt the PinePhone (and more recently the PinePhone Pro) made by Pine64. I’ve unfortunately not had it in my budget to acquire a new Pro version, so had to settle on developing on the first-gen Community Edition instead. The project outlined here is by no means locked to running on just these devices. If you have something like a Librem 5 by Purism, see how you can make it work!
In a previous article, I wrote about a new (and now maturing) framework called Tauri that I’ve started using to replace my old Electron-based projects. Unlike Electron, it uses Rust for handling all backend functionality, and allows for using web technologies to build your UI!
Even though I initially used Tauri to create a new desktop application, I thought it would be awesome to test out its capabilities running on the PinePhone! Let’s get to the good stuff, shall we?
Starting Off
The Tauri documentation provides excellent guides on creating new projects from scratch using their command line tool, including the ability to generate a complete skeleton using the front-end framework of your choice. Because I already had developed a web app using React, I already had the UI code structure in place. Since that was the case, all I needed to do was create the necessary Rust and configuration files needed by Tauri in the project directory:
Install CLI tool → yarn add -D @tauri-apps/cli
Initialize Tauri → yarn tauri init
If you’re creating a brand new project from scratch and you need to generate all the needed files for both front and backend, you’d run:
yarn create tauri-app
Backend Functions
Because I was building a dashboard application that needed to make regular GET requests to a Raspberry Pi on the local network, I had to make sure to include the same backend Rust function that the other versions of my app use to make these requests.
With Tauri, there’s no need to create a preload.js
file for the UI to call backend functions. Instead, all that’s needed is the @tauri-apps/api
library added to your package.json
file. You can then invoke the function from your JavaScript/React code with the following import:
import { invoke } from '@tauri-apps/api/tauri'
Using invoke
, you can then call your backend function by name, passing any arguments necessary. For my application, I make this call using a JavaScript function that passes the URL endpoint that I am making the request to in order to retrieve a particular sensor value:
The corresponding backend function gets included in the main.rs
file that Tauri creates in the projects src-tauri
directory:
It’s important to keep in mind that since this application is being written to run specifically on the PinePhone (or some other mobile Linux device), component sizes and window dimensions need to be taken into consideration.
Binary Creation
Once you’ve gone through the process of setting up your interface and any backend function calls, tested and debugged everything, you probably want to build a final product! Because these devices run Linux, Tauri will build a .deb
and .AppImage
binary for running and distributing your application. Building everything is as simple as running:
yarn tauri build
I did notice an issue with the automated AppImage
build script while trying to run on the aarch64
platform, so to successfully finish building the AppImage for my app, I simply downloaded and ran the appimagetool
utility to finish packaging:
Test It Out!
After that, you’ll end up with a shiny new AppImage with everything required to run built-in! Simply make it executable and run it to enjoy your new PinePhone (or similar) app!
A Word of Warning
I love my PinePhone, but when it comes to doing all of the development solely on the device, I’d advise against it. It’s plenty capable, but hot reloading can take longer than you’d like, and the same goes for building the final binary.
I found doing the majority of development and debugging on a separate ARM-powered device (my Raspberry Pi 4) was much quicker. Once you figure out the right window dimensions, the devpreview still provides an accurate look as to how the app is coming along.
After building the final executable on the Pi, it’s super simple to transfer over to the PinePhone using either scp
or a graphical SFTP
tool!
Next Steps
Curious to see what you can make with this? Head over to the Gitlab repo and check it out!
I hope to see even more great mobile Linux apps out there powered by Tauri in the near future. For those of you interested in Android development, Tauri also has mobile capabilities currently in alpha!
I've also published a fairly lengthy walk-through of how to build such an Android app over on Medium that I encourage you to check out if interested. I'll be publishing it here as well in the near future. 🌟