plain-app Documentation

PlainApp is an open-source app that lets you securely manage your phone from a web browser. Access files, media, contacts, SMS, calls, and more through a...

RAW Doc

Technical Documentation: plainhub/plain-app

ℹ️ Provenance: Multi-Tier Ingestion Β· CodeWiki Reference

Overview (`README.md`)

PlainApp

PlainApp is a free, open-source Android app that turns your phone into a self-hosted management hub you can access from any web browser on the same network β€” no accounts, no cloud, no subscriptions. Whether you need to transfer files, read SMS, browse photos, or mirror your screen, PlainApp puts full control back in your hands.



Why PlainApp?

Most phone-management tools either route your data through their own servers, lock features behind subscriptions, or plague you with ads. PlainApp is different:

  • 100% local β€” your data never leaves your network
  • End-to-end encrypted β€” every connection is secured with TLS + XChaCha20-Poly1305
  • Completely free and ad-free β€” no purchases, no upsells, ever
  • Fully open-source β€” audit the code, build your own binary, or contribute

Features

🌐 Web-Based Phone Management

Open a browser on any desktop or laptop connected to the same Wi-Fi network and get a full dashboard to manage your Android device β€” no app installation required on the computer side. Supports PWA so you can pin it to your desktop like a native app.

Category What you can do
Files Browse internal storage, SD card, and USB drives; upload, download, rename, delete
Media View and manage photos, videos, and audio; stream them directly in the browser
Contacts View, search, and manage your contacts
SMS & Calls Read messages and call logs; send SMS from your desktop
Apps List installed apps and export APKs
Notifications Mirror phone notifications to the browser in real time
Screen Mirror Live-stream the phone screen to the browser with audio and remote control support
Device Info Check battery, storage, network, and system details

πŸ“± Built-in Android Tools

PlainApp is also a capable standalone app β€” not just a server:

  • Markdown Notes β€” write and organize notes with a clean editor
  • RSS Reader β€” follow your favorite websites with a distraction-free reader
  • Video & Audio Player β€” full-featured media player with playlist support
  • TV Cast β€” cast media to any DLNA/Chromecast-compatible TV
  • Peer-to-Peer Chat & File Sharing β€” share files and messages directly between devices without a server
  • Pomodoro Timer β€” stay focused with a built-in work timer
  • Sound Meter β€” measure ambient noise levels in real time

πŸ”’ Privacy & Security

  • Zero data sent to any third-party server
  • All traffic between phone and browser is encrypted (TLS + XChaCha20-Poly1305)
  • No account registration required

Video: https://www.youtube.com/watch?v=TjRhC8pSQ6Q

Reddit: https://www.reddit.com/r/plainapp

Discord: https://discord.gg/RQWcS6DEEe

QQ Group: 812409393

How PlainApp Compares

Feature PlainApp AirDroid KDE Connect AnExplorer Pushbullet
Open source βœ… ❌ βœ… βœ… ❌
100% local / no cloud required βœ… ⚠️ partial βœ… βœ… ❌
End-to-end encrypted (local) βœ… ⚠️ paid ❌ ❌ ❌
Ad-free βœ… ⚠️ paid βœ… ⚠️ paid ⚠️ paid
Free all features βœ… ⚠️ freemium βœ… ⚠️ freemium ⚠️ freemium
Web browser access (no desktop app needed) βœ… βœ… ❌ ❌ βœ…
File manager (browser UI) βœ… βœ… ⚠️ limited βœ… ❌
SMS from desktop βœ… βœ… βœ… ❌ βœ…
Screen mirroring βœ… βœ… βœ… ❌ ❌
Media streaming in browser βœ… ⚠️ limited ❌ ❌ ❌
Notification mirroring βœ… βœ… βœ… ❌ βœ…
Built-in RSS reader βœ… ❌ ❌ ❌ ❌
Markdown notes βœ… ❌ ❌ ❌ ❌
P2P chat & file sharing βœ… ⚠️ paid ❌ ❌ ⚠️ limited
TV casting (DLNA/Chromecast) βœ… βœ… ❌ ❌ ❌
PWA support βœ… ❌ ❌ ❌ ❌
No account required βœ… ❌ βœ… βœ… ❌

βœ… Fully supported   ⚠️ Partially supported or requires paid plan   ❌ Not supported

Donations :heart:

This project needs you! If you would like to support this project's further development, the creator of this project or the continuous maintenance of this project, feel free to donate.

Your donation is highly appreciated. Thank you!

Screenshots

Android App

Web Dashboard

Compatibility

PlainApp requires Android 9.0 or higher.

FAQ

https://plainapp.app/docs

Support

PlainApp is fully open-source.
If you have any doubts, you're free to review the code, build your own version, or simply choose not to use it.

If you run into issues, feel free to open a GitHub issue β€” I'm always happy to help.

Please don’t leave a one-star review without giving it a fair try.

Work on plain-core

Keep plain-core next to this repository. Run from this repository root.

bash
./scripts/core local        # Use local plain-core
./scripts/core local --off  # Stop using local paths
./scripts/core update       # Lock this project to the latest remote commit

Build

  1. Generate release.jks file under $rootProject/app folder.
bash
keytool -genkeypair -v -keystore ./app/release.jks -alias release -keyalg RSA  -keysize 4096 -validity 36500
  1. Create keystore.properties file with following content under $rootProject folder.
text
storePassword=
keyPassword=
keyAlias=release
storeFile=release.jks

Overview (`plain-common/README.md`)

plain-common

Reusable Kotlin Multiplatform code extracted from PlainApp. Source packages are
kept unchanged under com.ismartcoding.plain.

The module includes common helpers, crypto, extensions, logcat,
and XML/RSS support. Supporting sources are included here so this module
has no dependency on the host application.

BLE protocol and native codec adapters belong to plain-rs features. Platform GATT adapters stay in the host shared module. This Kotlin library contains no BLE source.

Maven coordinates

kotlin
implementation("com.ismartcoding:plain-common:0.1.7")

Add the public GitHub Pages Maven repository to the consuming project's
repositories:

kotlin
maven {
    url = uri("https://plainhub.github.io/plain-app/maven")
}

Then add the dependency shown above. Releases use tags named
plain-common-v<version>; the default local version can be changed with
-PplainCommonVersion=….

Publishing

The Publish plain-common GitHub Actions workflow builds the KMP publications
and adds the Maven files to the dedicated maven branch under maven/ when a
plain-common-v<version> tag is pushed. The workflow also syncs policy.html and terms.html from main so their existing public URLs stay available. It can also be run manually with a
version number. The workflow uses its temporary GITHUB_TOKEN; no publishing
credentials are stored in the repository.

For a local Maven cache, run ./gradlew :plain-common:publishToMavenLocal.


Overview (`plain-ui/README.md`)

plain-ui

Shared Compose Multiplatform components in com.ismartcoding.plain.ui.
This is the component selection entry point for PlainApp and PlainNet (plain-router-app).
Before editing UI, choose the scene below, open its compiled example, and read the actual component signature. Pages compose existing components and connect state and events.

Scene Use Compiled example
Page and top bar PScaffold + PTopAppBar ComponentShowcasePage
Primary, outlined, text action PFilledButton, POutlinedButton, PTextButton; size via ButtonSize, role via ButtonType Button states
Text input, password, validation PTextField; choose enabled and readOnly independently Form states
Single choice between a few options PSegmentedButtons Segmented buttons
Cards, list rows, banners, filters, removable chips PCard, PListItem, PBanner, PFilterChip, PInputChip Component showcase
Bottom sheet PModalBottomSheet + PBottomSheetTopAppBar; primary actions use PSheetPrimaryActionsCard, overflow uses PSheetActionCard FileInfoBottomSheet
Confirmation and input dialog Host confirmActionAsync / DialogHelper, TextFieldDialog, RadioDialog; selection rows use PDialogRadioRow DialogHelper
Icon with label below PIconTextSmallButton for compact toolbar; PIconTextActionButton for shortcuts; PSheetPrimaryAction for sheet actions State showcase
Boolean / radio / simple icon control Official Material3 Switch, RadioButton, IconButton; use host icon shortcuts when applicable Dark theme choices
Media seek, animated waveform, countdown PlayerSlider, WaveSlider, CircularTimer PomodoroPage
Large document, scan, drag selection, fast scroll, pull refresh CodeEditor, QrCodeScanner, gridDragSelect, fastscroll and pullrefresh packages TextFilePage

The first eight scenes require the existing project components. Basic layout (Box, Row, Column), text, images and controls in the official-control row can use Compose directly. Specialized editor, scanner and gesture engines keep their own behavior; inspect their contracts before extending them. Host dialog helpers use each application's resources and state, and stay outside this library.

Use AppTheme as the complete theme entry. Keep the brand palette, soft dark text and AMOLED behavior; dynamic color is excluded. Shapes come from the theme: medium for ordinary cards/inputs, large for prominent preview/banner containers, smaller roles for nested surfaces, and CircleShape for capsules/discs. Exact dynamic geometry belongs to its specialized implementation. Brand sizes are defined in Shapes, not Material default sizes.

Public layout components accept a root modifier. Actions use onClick, enabled and onDismissRequest. Required actions have no default empty callback; optional actions are nullable and create no click target when absent. Each distinct public component has its own file; overloads of the same component may share it. Code comments use English and explain only non-obvious decisions.

Read parameter behavior in the source: PScaffold consumes horizontal insets and passes only top/bottom padding to content; PTextField renders its own error message; PInputChip.onClose determines whether the close target exists (onClick = null makes the whole chip a remove action); PListItem.dimmed is visual dimming and its two title extension slots are mutually exclusive. Sheet primary rows accept at most four actions, including in RTL. Button loading prevents interaction while preserving label width. Do not recreate these policies in business pages.

Run bash scripts/check-ui.sh from plain-app or plain-router-app after UI changes, followed by the host application's build. The shared Kotlin PSI checker resolves explicit imports, aliases, wildcard imports and fully qualified calls; it ignores comments and strings, rejects new raw Material page/sheet/button/form calls and literal shapes, and checks public library layout contracts. It generates the component symbol index under the application’s build/reports/ui-check/ from source. Legacy business occurrences are frozen by exact file, function, symbol and count in each application's scripts/ui-component-baseline.tsv; entries name remaining migration debt or specialized geometry. Do not add entries to get a new violation through. Delete an entry when migrating its owner. No package-wide exclusion is supported.

This syntax check does not perform whole-program type inference or detect an arbitrary layout recreating a component. Compiler checks, the scene index, examples and review remain necessary. The showcase includes disabled/loading/error/read-only states and RTL/large-text controls; device checks must also cover light, dark, AMOLED, TalkBack, keyboard and neighboring touch targets. Performance changes need release traces before claiming a measured speedup.

Maven coordinate: com.ismartcoding:plain-ui, repository https://plainhub.github.io/plain-app/maven.
The Publish plain-ui workflow publishes tagged plain-ui-v<version> releases on the dedicated maven branch. Consumers must upgrade after publication; local cross-project validation can selectively substitute plain-ui, preserving their own plain-common version.


--- METRICS ---