Phandroid — the Phanpy Mastodon web client, wrapped as a native Android app with Capacitor. Install via Obtainium; see the README.
  • JavaScript 80.7%
  • CSS 18.6%
  • Kotlin 0.5%
  • HTML 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Phandroid Buildhost 93cfde3a37
Some checks are pending
autofix.ci / autofix (push) Waiting to run
Pull Request into `production` from `main` / auto-pull-request (push) Has been skipped
Playwright Tests / test (push) Waiting to run
Deploy to Rollbar / rollbar-deploy (push) Has been skipped
chore(release): bump to 2.0.6 (auto, upstream merge)
2026-07-21 02:18:58 +00:00
.github feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
android chore(release): bump to 2.0.6 (auto, upstream merge) 2026-07-21 02:18:58 +00:00
assets feat(android): branded adaptive launcher icon and splash screens 2026-07-07 18:42:24 +02:00
compose feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
design feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
fastlane/metadata/android docs(dev): warn that Phandroid Dev is the bleeding-edge channel 2026-07-20 10:03:53 +00:00
public feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
readme-assets feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
scripts feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
src Merge remote-tracking branch 'upstream/main' 2026-07-21 02:17:34 +00:00
tests feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
.env docs: point public distribution at Codeberg (native Obtainium source) 2026-07-09 12:31:50 +02:00
.env.production feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
.gitattributes chore(upstream): configure Phanpy upstream sync (merge attrs + docs) 2026-07-08 07:25:00 +02:00
.gitignore chore: gitignore mail.env (never commit mail config) 2026-07-09 15:43:27 +02:00
.oxfmtrc.json feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
.release.env.example fix(dist): release-gitea.sh works on bash 3.2 + auto-loads token 2026-07-08 10:24:40 +02:00
capacitor.config.json release: 2.0.0 — rename applicationId to dev.umrath.android.phanpy; drop self-host refs 2026-07-11 07:23:33 +00:00
CHANGELOG.md chore(release): bump to 2.0.6 (auto, upstream merge) 2026-07-21 02:18:58 +00:00
CHANGELOG.phanpy.md feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
crowdin.yml feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
env.schema.json feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
i18n-volunteers.json feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
index.html feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
LICENSE Initial commit 2026-07-07 17:48:47 +02:00
lingui.config.js feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
package-lock.json feat(share): register Phandroid as an Android share target (#378) 2026-07-08 07:50:28 +02:00
package.json feat(share): register Phandroid as an Android share target (#378) 2026-07-08 07:50:28 +02:00
PHANDROID_CUSTOMIZATIONS.md release: 2.0.0 — rename applicationId to dev.umrath.android.phanpy; drop self-host refs 2026-07-11 07:23:33 +00:00
playwright.config.js feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
PRIVACY.MD feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
README.md docs(readme): clarify stable vs -dev APK naming for sideloaders 2026-07-20 15:11:45 +00:00
rollbar.js feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
SECURITY.md feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
vite.config.js feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00
wrangler.jsonc feat: import Phanpy web app as project base 2026-07-07 18:12:48 +02:00

Phandroid

This is a fork of Phanpy, with the goal of making it installable as an Android app.

It uses Capacitor to wrap the Phanpy web app into a native Android app — the same approach iPhanpy takes for iOS. Rather than reimplementing the UI natively, Phandroid ships the proven Phanpy web client inside an Android WebView shell and adds a thin, well-isolated layer of Android-specific tweaks (deep-link OAuth, native camera, in-app browser, hardware back button, edge-to-edge insets).

Built with LLM: this Android port — the Capacitor integration, the Android-specific override layer and the surrounding tooling — was created with the assistance of a large language model.

Status: released and installable via Obtainium from Codeberg (see Installation). Supports OAuth login, native camera, an in-app browser, an Android share target, edge-to-edge UI and optional FOSS push (UnifiedPush). See CHANGELOG.md and PHANDROID_CUSTOMIZATIONS.md for details.

Channels

Phandroid ships as two side-by-side apps, each tracking a different Phanpy branch. Install either — or both; they don't conflict (separate app id, data and OAuth scheme).

Phandroid (stable) Phandroid Dev (bleeding)
applicationId dev.umrath.android.phanpy dev.umrath.android.phanpy.dev
OAuth scheme phandroid:// phandroiddev://
tracks Phanpy production Phanpy main
updates curated releases — Codeberg / Obtainium + F-Droid automatic, every upstream change — Codeberg (as prerelease) + F-Droid

Start with Phandroid. Phandroid Dev sees new Phanpy changes sooner but may break more often; it installs next to the stable app with its own accounts and settings.

Installation

⚠️ Upgrading from a pre-2.0.0 build? Reinstall required. Version 2.0.0 changes the app package id to dev.umrath.android.phanpy. Android treats the new package as a different app, so it cannot update in place: uninstall the old Phandroid, then install this one from the Codeberg URL below. Logged-in accounts, settings and push registration do not transfer and must be set up again (the signing key and the phandroid:// login are unchanged). If you added the app in Obtainium from the old source, remove it there and re-add the Codeberg URL.

Phandroid is distributed as a signed APK — not on the Play Store.

  1. Install Obtainium (from F-Droid or its GitHub releases).

  2. In Obtainium tap Add App and paste the Codeberg repo URL:

    https://codeberg.org/umrath/Phandroid
    

    Obtainium recognises it as a Forgejo (Codeberg) source.

  3. Tap Add, then Install — this gives you the stable Phandroid. Obtainium ignores prereleases by default, so it tracks stable releases only and updates automatically.

To also follow Phandroid Dev, add the same URL a second time and, in that entry's options, turn on Include prereleases and set the release-filter regular expression to -dev. dev builds are published as prereleases (tag …-dev), so the plain entry above never sees them — stable stays stable — while this second entry tracks the dev app, which installs alongside the stable one as a separate package.

Via the F-Droid repo (auto-updates)

Add the self-hosted F-Droid repository once, then install Phandroid from it — a compatible client (the F-Droid app, Droid-ify or Neo Store) then checks it for updates automatically.

  1. In your F-Droid client open Settings → Repositories → Add repository and paste:

    https://fdroid.umrath.dev/repo?fingerprint=732DC12007C2873A07AA5E27DB47667F5A08E392C882E13C46D1480C7727CF19
    

    The fingerprint pins the repo to its signing key — keep it in the URL.

  2. Refresh the repo — it lists both apps: Phandroid (stable) and Phandroid Dev (bleeding). Install whichever you want, or both side by side.

The repo's APKs use the same signing key as the Codeberg releases, so you can move between this repo, Obtainium and a sideloaded APK without reinstalling.

Prefer Obtainium? It can also add this F-Droid repo directly (Obtainium → Add App → source type F-Droid Third-Party Repohttps://fdroid.umrath.dev/repo), which lists both apps — an alternative to the Codeberg/Obtainium route above.

Direct APK (sideload)

Download the latest phandroid-vX.Y.Z.apk (the stable Phandroid) from the releases page and open it to install (allow "install unknown apps" for your browser / file manager if prompted). The …-vX.Y.Z-dev.apk prereleases are Phandroid Dev — a separate app, not an update to the stable one.

Push notifications (optional, FOSS — no Google)

Phandroid uses UnifiedPush: encrypted Web Push, decrypted on-device, with no Google/FCM.

  1. Install a UnifiedPush distributor, e.g. Sunup. Open it once and grant its permissions (notifications + battery-optimization exemption — it keeps the push connection alive).
  2. In Phandroid go to Settings → Push Notifications (beta), turn it on and choose which notification types you want.
  3. Allow the two prompts Phandroid then shows: the notification permission and the battery-optimization exemption (so push keeps working reliably).

Building

Phandroid is a Capacitor app: the web client is built with Vite, then wrapped by the native Android project under android/.

Prerequisites

  • Node.js 22+ and npm 10.x
  • Android Studio with an Android SDK (platform android-35 and build-tools 35) — required to compile and run the APK
  • A JDK 1721 (Android Studio bundles a suitable JDK; JDK 21 is known to work)

1. Install and build the web app

npm install
npm run build          # outputs to dist/
npx cap sync android
npx cap open android

Then run the app on an emulator or a connected device from Android Studio.

2b. Or build a debug APK from the command line

Point Gradle at your SDK by creating android/local.properties with sdk.dir=/absolute/path/to/Android/sdk, then:

npx cap sync android
JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home" \
  ./android/gradlew -p android :app:assembleDebug

The APK is written to android/app/build/outputs/apk/debug/app-debug.apk.

Live reload during development

npx cap run android --livereload --external

Regenerating the launcher icon / splash

npx capacitor-assets generate --android

(reads assets/logo.png; the adaptive icon background colour is set in android/app/src/main/res/values/ic_launcher_background.xml).

Credits