Platform overview

Last updated 2026-09-21

A Plum Box is a small server in someone's home. It stores their files and photos, holds their identity, and runs apps. You write apps for it the way you would write apps for a server you control — except the server belongs to your user, and Plum is not in the request path.

Three consequences shape everything below:

  • The data never leaves the box. Your backend runs on the box, next to the files it reads.
  • The user's box is the authority on identity and permission. There is no Plum account system in the middle: consent is given on the box, and the box enforces it.
  • You sign your own releases. The store countersigns what passes checks or review, but the signature that lets your app run is yours. See Signing and trust.

The four shapes

An app is one of these, or several of them together.

Shape What it is How it ships
Service (server .plu) A backend that runs on the box: its own uid, its own data directory, resource limits, a unix socket, and a control socket back into the box. Plum Store, or installed directly to a box you paired with
Panel (web .plu) A web UI served by the box and shown in the box's web shell or in the Plum mobile app. Uses the JS SDK. Plum Store, or direct install
Companion app A native app on iOS, Android or desktop that connects to the box as a registered OAuth client. Apple App Store / Google Play / your own channel
Standard endpoints A service that speaks WebDAV, CalDAV or CardDAV, so the OS's own apps connect with no Plum app at all. Planned — see the note below

One store listing is a combination. A downloader is a service plus a panel. A messenger is a service plus a companion app, and maybe a panel for its settings. A calendar is a service plus standard endpoints plus a small panel.

There is a fifth kind of listing that installs nothing: a compatible app. If your existing app (a notes app, a photo editor) just wants the box as storage, register it in the console under Register a compatible app, register its OAuth clients, and it is listed as working with Plum Box. No .plu, no code on the box, and the only things Plum holds are the registered client_id, the scopes it may ask for, and the ability to disable it.

Version note: protocol mounts (/dav/...) and the protocols[] manifest field need core 1.11 or newer. Everything else on this page is implemented unless marked otherwise. Where a page says planned, do not build on it yet.

What runs where

┌───────────────────────── clients ──────────────────────────┐
│  Plum app (iOS/Android)   your companion app   web browser  │
│        └──── connect SDK: discovery, login, LAN/P2P/relay ──┘
├──────────────────────── the box (core) ────────────────────┤
│  identity, consent, permission  (OAuth PKCE, PAT, scopes,   │
│                                  entitlements)              │
│  app runtime  (supervisor, /apps/<id>/svc proxy, control    │
│                socket, resource limits, signature checks)   │
│  core services  (files, photos, users, sharing, events)     │
├───────────── Plum services (convenience, replaceable) ─────┤
│  relay   discovery   store   OTA   identity                 │
└─────────────────────────────────────────────────────────────┘

The bottom layer is convenience. A box on the same network as its user works without any of it: apps installed, services running, files served. The store is how apps get found and countersigned, not how they are allowed to run.

What the store controls

Three things, and it is worth knowing exactly which:

  1. Client registration. A companion app identifies itself with a client_id you register in the console. Boxes fetch the registry and refuse consent for a client_id they do not know, so an unregistered app cannot ask a user for access. See Companion apps.
  2. Entitlements. Paid features are proved by signed receipts the store issues for a box serial. The box verifies and caches them, and hands your app the list. Your app decides what to lock; the box only proves what was bought. See Publishing.
  3. Review and countersignature. A version that passes the automatic checks is countersigned checks (beta); a version a person reviews is countersigned reviewed (public). A box at the default trust level installs countersigned bundles. See Signing and trust.

Money

Plum does not take payment inside apps. Paid services and paid features (entitlements) are bought in the box UI or on the web, never through an in-app purchase flow, which is what keeps a companion app inside Apple's and Google's rules: the companion app is free and does not steer the user to a payment page.

There is no payment provider connected today. SKUs are recorded in the console and entitlements are granted by a developer (test grants for a box serial) or by an admin. Build your app so that it reads entitlements and degrades gracefully; the purchase path will be added under the same receipts.

Where to go next