3 minute read

In my last post, I explored a way to generate a large word list for passphrase generation. But I couldn’t find any Android app that allows me to actually take this list and generate passphrases! That’s a pretty good excuse for me to play around with progressive webapps (PWA) to see if I could get an LLM to write me a simple app to install and run on my phone.

Writing (Generating) the PWA

These days it is extremely easy to create a simple web app. I just prompted GPT-OSS with my requirements and got what I wanted in a few iterations. Since the word list is huge, instead of directly reading and generating the standalone html file, it is better to prompt the LLM to generate a script, which takes the word list as an input and generates the html file.

For a PWA, in addition to the html, you also need a service worker that specifies how to cache assets, a manifest file with the app’s metadata, and some icon files. I just took some existing generic app icon files from the internet, but it wouldn’t be hard to generate it with local AI either.

Very quickly I got all the files ready: I have index.html, service-worker.js, manifest.json, icon-512.png and icon-192.png in a folder locally.

Tailscale Serve

To deploy a PWA to my phone, there is a step that is usually a little tricky to figure out, which is that I need to serve the web app with https. But luckily this is a very easy problem to solve these days with Tailscale.

You need to first sign up for an account, then run a Tailscale client on both the development machine and your phone and add both devices to the same tailnet. All of this is free, although slightly annoyingly this step relies on using third party services like Google and Tailscale for authentication. But at least it is free and none of the data goes through their servers.

Here is one extra step that took me a while to figure out: now, you should go to the Tailscale admin console and change your machine’s name to a name unique to the app you’re trying to deploy. This allows you to deploy multiple apps using the same method, otherwise chrome on Android thinks they’re all one app and refuses to install it multiple times. So let’s say you renamed the machine to passphrase.

Then, you can find some way to serve the website locally, like running python3 -m http.server in the folder with the static assets. With that running (say on port 8000), you can then use sudo tailscale serve --https 8001 8000 to serve the same content to port 8001 but with SSL certs magically figured out, without chrome complaining that your cert is broken in some way. Having dealt with certs before, I am extremely grateful that this is such a simple and seamless step.

That command would give you a url that you can open in chrome on Android. Now chrome will prompt you to install the PWA. Install it and that’s it! As far as I can tell you can just kill the commands on your machine, delete all the files if you want, and the app will work just fine offline on your phone. It just looks and works like any other app.

As a final clean up step, you probably want to change the machine name in Tailscale back to the original name. If you’d rather not deal with Tailscale anymore, you can also get rid of all your clients and delete your account, but I’ve found Tailscale to be quite useful for things like this.

Update: Tailscale Service

That weird step of renaming the machine just to deploy an app can be eliminated now with Tailscale Service! Incredible. I’m going to deploy so many apps.