Shared Rust code for PlainApp desktop, mobile and command-line hosts.
plain-core/
├── Cargo.toml Builds and tests the five packages together
├── plain-rs/ Domain services, storage, crypto and protocols
├── plain-server/ Server, GraphQL and host communication
├── plain-media/ Media catalog, scanning and processing
├── plain-inference/ Model inference
├── plain-cli/ The plainapp command-line executable
├── schema/ GraphQL and SQLite definitions
└── scripts/ Development tools
Each plain-* directory is a Rust package managed by the root Cargo.toml.
Desktop shell and mobile JNI/C ABI code live in plain-desktop and plain-app, respectively.
Requires Rust 1.99+, Python 3.10+ and a C compiler.
cargo check --workspace --locked # Check all packages for compile errors
cargo test --workspace --locked # Test Rust functionality in all packages
cargo run -p plainapp -- run --help # Build plainapp and show run-command helpRegenerate GraphQL and SQLite artifacts from the current Rust implementation with Node.js and Rust:
node scripts/gen-schema.mjs --writeThe command writes schema/database.sql, the main schema fragments in schema/api/, and schema/guest-api.graphqls and schema/peer-api.graphqls. It builds and runs the three schema snapshot checks. Omit --write to verify the generated files without updating them.
Desktop consumes these same fragments. After a contract change, run yarn graphql:codegen in the sibling plain-desktop checkout to refresh its operation types. Mobile reads the Core schema directly and keeps no separate SDL copy.
plainapp is a single executable with the web UI compiled into it, and a Linux host runs it as the systemd service plainapp.
curl -fsSL https://raw.githubusercontent.com/plainhub/plain-core/main/install.sh | bashIt detects the architecture, downloads the matching release, installs the dependencies and the systemd unit, starts the service, and prints the addresses to open.
sudo plainapp passwd # admin password, prompted twicehttp://<host>:8080— HTTPhttps://<host>:8443— HTTPS with a self-signed certificate created on first start forplainapp.localandlocalhost
cargo build --release --locked -p plainapp
install -m 0755 target/release/plainapp /usr/local/bin/plainapp
sudo plainapp install # ffmpeg, Samba, Avahi
sudo plainapp install --with-libreoffice # add DOC/DOCX preview
sudo systemctl enable --now plainappplainapp install writes /etc/systemd/system/plainapp.service, whose ExecStart is /usr/local/bin/plainapp run, so that path is required. It does not copy the binary, and it neither enables nor starts the service.
The Web UI is compiled into plain-server and shared by the CLI and mobile libraries. From the sibling plain-desktop checkout, run bash build.sh to build directly into plain-core/plain-cli/src/web_dist, then commit the generated assets with the corresponding core changes. Consumers receive the assets through their pinned core Git dependency; no separate mobile Web resource copy is needed.
Set PLAIN_WEB_DIST to an absolute frontend build directory to override the embedded build input. Mobile Gradle builds also accept -PplainWebDist=/absolute/path/to/dist. Explicit inputs must exist and contain index.html; invalid inputs fail the build. A checkout without the default plain-cli/src/web_dist directory and without an override builds with API support only.
run --web-root <directory> serves a frontend bundle from disk instead of the compiled one, which is how a local frontend build is tried without rebuilding:
[Service]
ExecStart=/usr/local/bin/plainapp run --web-root /opt/plainapp/webPorts come from user settings and default to 8080 and 8443. Data and cache live in $HOME/.plainapp/data and $HOME/.plainapp/cache; the unit sets no User=, so it runs as root and uses /root/.plainapp. Override with --data-dir, --cache-dir, --tls-cert, --tls-key or the PLAINAPP_DATA_DIR, PLAINAPP_CACHE_DIR, PLAINAPP_TLS_CERT and PLAINAPP_TLS_KEY environment variables.
plainapp update only reports that self-update is not implemented, so an upgrade replaces the executable and restarts the service:
install -m 0755 new/plainapp /usr/local/bin/plainapp
sudo systemctl restart plainappsudo plainapp uninstall removes the unit, the certificate and the data directory. Pass --keep-config and --keep-data to retain them.
A v* tag builds the frontend from plain-desktop, compiles it into plainapp for Linux amd64 and arm64, and attaches the archives to the GitHub release.
Keep plain-core next to plain-desktop or plain-app. Run these commands in the desktop or app repository; its scripts/core calls plain-core/scripts/core-dependencies.py.
./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