# filex desktop app The filex explorer in its own window, with folder sync that keeps running in the background. Windows and Linux (x64 and arm64) and macOS (Apple Silicon) - and on every one of them there is a copy that runs without being installed. It is the same explorer the web app and embedders use, not a separate copy. It adds **several accounts at once**, **folders synced to your disk**, and **staying in the tray** so that sync runs with the window closed. It is **not** an admin console: the app opens your server's admin panel in your browser. ## In five minutes 1. **Install** it from the Microsoft Store or the Snap Store, with `snap` or `brew`, or download the file for your platform ([Install](#install)). Your server needs filex v0.11.0 or newer. 2. **Sign in**: type your server's address, sign in on the page your browser opens, and the browser hands the app a one-time code ([Signing in](#signing-in)). 3. **Keep a folder**: right-click it → **Keep on this computer**. It syncs both ways under one filex folder on your disk; everything else stays online-only in the window ([Keeping folders on this computer](#keeping-folders-on-this-computer)). With the Office editor app (or an ONLYOFFICE Document Server) on your server, Office documents on your own disk open in it too ([Opening documents from your computer](#opening-documents-from-your-computer)). --- ## Install ### From a store
Download from the Microsoft Store    Get it from the Snap Store
The Microsoft Store lists it as *filex File Manager* (Windows 10/11), the Snap Store as `filex-app` (Ubuntu's App Center finds it when you search for *filex*). Both install the same app as the downloads below and keep it up to date themselves; the app then leaves updating to them. ### With a package manager The desktop app is **`filex-app`** in every one of them; plain `filex` is the [CLI](CLI.md). | Platform | Command | Notes | |---|---|---| | Ubuntu and other Linux with snapd | `sudo snap install filex-app` | The Snap Store build, for x64 and arm64 (snapd picks the one for the machine). Two plugs are yours to connect, and the app asks for each only when it is needed, saying first what it allows: `password-manager-service` to keep the sign-in in your keyring, `removable-media` to sync a folder under `/media`, `/run/media` or `/mnt`. See [the plugs you connect](#the-plugs-you-connect), [the snap and the sandbox](#the-snap-and-the-sandbox), and for the nightly build [the Snap Store's channels](#the-snap-stores-channels). | | macOS 13+ (Apple Silicon) | `brew install brf-tech/filex/filex-app` | Homebrew tap [`BRF-Tech/homebrew-filex`](https://github.com/BRF-Tech/homebrew-filex); `brew upgrade` keeps it current (the Mac app does not update itself). The app is not signed with a Developer ID, so the first launch is blocked once, as below. | | Windows 10/11 | [Microsoft Store](https://apps.microsoft.com/detail/9PKXDJLVZWXW) - *filex File Manager* | **The one code-signed Windows build** (Microsoft signs it): no SmartScreen prompt, and the Store updates it. Beside the installer below, both read the same accounts and folders (App settings says so). | | Windows 10/11 | `winget install BRFTech.filex-app` - **not installable yet** | The same per-user installer as the download below, updating itself the same way. The desktop app's package is still waiting for its first review by the winget moderators, and until it is approved no release touches it - a new submission would put it back at the end of their queue - so `winget` does not find it yet; once approved, every release updates it. The [CLI](CLI.md)'s package, `BRFTech.filex`, is on winget already. | ### Download | Platform | File | What it does | |---|---|---| | Windows 10/11 (x64) | [`filex-desktop-x64.exe`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-x64.exe) | Installer, for **your user only** (`%LOCALAPPDATA%\Programs\filex`): no administrator rights, and the app can replace its own files, so it updates itself quietly. Adds a Start-menu entry. | | Windows 10/11 (x64) | [`filex-desktop-portable-x64.exe`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-portable-x64.exe) | **Portable** - nothing is installed. Run it from anywhere: a USB stick, `Downloads`, a work machine you may not install software on. It keeps its files in a `filex-data` folder beside itself ([Portable](#portable-windows)). | | Windows on Arm (arm64) | [`filex-desktop-arm64.exe`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-arm64.exe) · [`filex-desktop-portable-arm64.exe`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-portable-arm64.exe) | The same installer and portable copy for arm64: no emulation, and the sync engine inside is arm64 too. An installed copy updates itself to the next arm64 build. | | Linux (any, x64) | [`filex-desktop-x86_64.AppImage`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-x86_64.AppImage) | **Portable** - no installation. `chmod +x` and run. On Ubuntu 23.10 and later it needs a one-time step first: [AppImage on recent Ubuntu](#appimage-on-recent-ubuntu). | | Debian / Ubuntu (x64) | [`filex-desktop-amd64.deb`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-amd64.deb) | System-wide install (package `filex-app`), appears in your applications menu. | | Fedora / openSUSE (x64) | [`filex-desktop-x86_64.rpm`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-x86_64.rpm) | The same, as an RPM (package `filex-app`). | | Linux (arm64) | [`filex-desktop-arm64.AppImage`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-arm64.AppImage) · [`filex-desktop-arm64.deb`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-arm64.deb) · [`filex-desktop-aarch64.rpm`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-aarch64.rpm) | The same three for arm64, each updating itself from its own arm64 feed. The AppImage needs the same [one-time step on recent Ubuntu](#appimage-on-recent-ubuntu). | | macOS 13+ (Apple Silicon) | [`filex-desktop-arm64.dmg`](https://github.com/BRF-Tech/filex/releases/latest/download/filex-desktop-arm64.dmg) | Drag to *Applications*. **Unsigned** - see the first-launch note below. Intel Macs: no build; the web app works there. | Which one is yours: `uname -m` on Linux (`x86_64` is x64, `aarch64` is arm64), Settings → System → About → *System type* on Windows. The web app's offer of the desktop app and [filex.sh](https://filex.sh/#downloads) read it from the browser (Chromium-based browsers name the processor, Firefox on Linux says `aarch64`); where the browser does not say (Safari, Firefox on Windows), the x64 file is offered with the arm64 one beside it. ```bash # Debian / Ubuntu sudo apt install ./filex-desktop-amd64.deb # arm64: ./filex-desktop-arm64.deb # Fedora / openSUSE sudo dnf install ./filex-desktop-x86_64.rpm # arm64: ./filex-desktop-aarch64.rpm # openSUSE: sudo zypper install ./filex-desktop-x86_64.rpm # Anything else chmod +x filex-desktop-x86_64.AppImage # arm64: filex-desktop-arm64.AppImage ./filex-desktop-x86_64.AppImage ``` On Linux the installed app's command is **`filex-app`** - `filex` is the [CLI](CLI.md). ```powershell # Windows, nothing installed: put the .exe where you want it and run it. # The folder it makes beside itself is the whole of what it leaves behind. .\filex-desktop-portable-x64.exe ``` > ⚠ **The downloads are not code-signed yet** (the Microsoft Store build is: > Microsoft signs it). Windows SmartScreen will show > "Windows protected your PC" - *More info* → *Run anyway*. To be certain of > what you downloaded, check it against `checksums.txt` on the release. > > ⚠ **macOS, first launch.** The app is not signed with a Developer ID, only > *ad-hoc sealed*, so a downloaded copy is blocked once: open **System Settings → > Privacy & Security → Open Anyway** (older versions: right-click → *Open*). **Server requirement:** filex **v0.11.0 or newer**. The app signs in through two endpoints older servers do not have, and says so rather than failing silently. --- ### AppImage on recent Ubuntu On Ubuntu 23.10 and later (24.04 LTS included, and the distributions built on them) the AppImage needs two things before it opens. The `.deb` needs neither, so on Ubuntu it is the simpler choice. 1. **FUSE 2.** An AppImage mounts itself with FUSE 2, which Ubuntu no longer installs by default (since 22.04). Without it nothing opens; from a terminal it says `dlopen(): error loading libfuse.so.2`. ```bash sudo apt install libfuse2t64 # Ubuntu 24.04 and later; on 22.04: libfuse2 ``` 2. **Room for Chromium's sandbox.** The app's pages run in Chromium's sandbox, built from user namespaces, and since 23.10 Ubuntu lets a program create them only if an AppArmor profile allows it (`kernel.apparmor_restrict_unprivileged_userns=1`). The `.deb` and the `.rpm` carry a setuid helper (`chrome-sandbox`) instead; an AppImage cannot. This profile gives that one permission to the AppImage, and only to a file named like it in a home folder: ```bash sudo tee /etc/apparmor.d/filex-appimage > /dev/null <<'EOF' abi , include profile filex-appimage @{HOME}/**/filex-desktop-*.AppImage flags=(unconfined) { userns, include if exists } EOF sudo apparmor_parser -r /etc/apparmor.d/filex-appimage ``` It is read again at every boot. The image can live in any folder under your home under its release name (`filex-desktop-x86_64.AppImage` or `filex-desktop-arm64.AppImage`), which its updates keep. To take the profile away again: `sudo apparmor_parser -R /etc/apparmor.d/filex-appimage && sudo rm /etc/apparmor.d/filex-appimage`. **Without the profile the app says so itself.** Every Linux build starts through a small launcher (`filex-app`; the Electron binary beside it is `filex-app-bin`) that checks the sandbox can be built (not in the snap: [the snap and the sandbox](#the-snap-and-the-sandbox)). When it cannot, the launcher shows these steps - in a window where zenity or kdialog is installed, and in the terminal in any case - and exits with code 78; the app does not open. The same holds for an AppImage added to the menu by AppImageLauncher, Gear Lever or appimaged: neither the menu entry they copy from the image nor the image's own entry point (`AppRun`, which passes on exactly the arguments it was given) switches the sandbox off. > ⚠ Starting the app with `--no-sandbox` yourself also opens it, and is not a > fix: it switches the sandbox off, so a page that got the better of the viewer > would run with your account's access to your files and to the tokens the app > holds. The launcher passes a `--no-sandbox` you typed through and, outside > the snap, never adds one. Use the profile, or the `.deb`. ### The snap and the sandbox The snap starts the app with Chromium's own sandbox switched off (`--no-sandbox`) and relies on snapd's strict confinement instead: an AppArmor profile, a seccomp filter and a mount namespace of its own around the whole app. There is nothing to connect for it, and the launcher checks nothing in the snap. The confinement keeps the app, all of it, away from the rest of the system, but does not wall the pages the app shows off from the app itself. A page that got the better of the viewer would have what the app has inside the snap: the files in your home folder that the `home` interface reaches, the network, and the tokens the app holds. In the `.deb`, the `.rpm` and the AppImage each page also runs in Chromium's sandbox, with none of that. If the difference matters on your machine, install the `.deb` or the `.rpm`. Why the snap is built this way: [CONTRIBUTING.md → Desktop snap without Chromium's sandbox](CONTRIBUTING.md#desktop-snap-without-chromiums-sandbox). The snap is built on `core24` (Ubuntu 24.04) with Snapcraft's GNOME extension, for x64 and arm64. Its first install also brings the GNOME 46 runtime (`gnome-46-2404`), the graphics libraries (`mesa-2404`) and the GTK themes (`gtk-common-themes`), which other snaps share. The window opens through X11 (XWayland on a Wayland desktop). Every release installs the snap on x64 and arm64 Ubuntu 24.04 machines and checks this confinement before it publishes. #### The plugs you connect Two of the snap's plugs reach more than the app's own files, so connecting them is your choice and the Snap Store does not connect them for you. The app asks snapd whether each is connected (`snapctl is-connected`) and, when one is not, says what connecting it allows before it shows the command: | Plug | What connecting it allows | When the app asks | |---|---|---| | `password-manager-service` | filex keeps your sign-in tokens encrypted in the system keyring (GNOME Keyring or KWallet). The plug gives the snap access to the secrets stored in your keyring, and other apps that can reach your keyring can also read the secrets filex puts there. | Before the first sign-in. Without a keyring filex keeps no sign-in at all (never on disk in plain text), so the sign-in window explains this and shows the command instead of starting a sign-in. | | `removable-media` | filex reads and writes every folder under `/media`, `/run/media` and `/mnt`, not only the one you chose. | When you choose a folder there to sync into: a folder in *App settings → Synced folders*, the filex folder that *Keep on this computer* asks for, or a new place for it ([The filex folder on this computer](#the-filex-folder-on-this-computer)). Nothing is paired or moved; the message says what the plug allows and has a button that copies the command. | ```bash sudo snap connect filex-app:password-manager-service # then restart filex sudo snap connect filex-app:removable-media # then choose the folder again ``` The command the app shows names the snap as snapd runs it, so a parallel install (`filex-app_beta`) gets its own name. When snapd says the keyring plug is connected and the keyring still does not answer, the sign-in window says to start or unlock the keyring instead. When snapd gives no answer, the sign-in window shows the command and a folder is paired as chosen. ### The Snap Store's channels `sudo snap install filex-app` follows `stable`. The other channels are there to try what comes next: | Channel | What it serves | What puts it there | |---|---|---| | `stable` | The release. | Every release, x64 and arm64. | | `candidate` | The release - the same revision as `stable`. | Every release, with `stable`. | | `beta` | The release - the same revision as `stable`. | Every release, with `stable`. | | `edge` | The newest build: the release on the day it ships, then the **nightly** build of each change that passed the nightly test run, x64 and arm64. | Every release, and every night that made a nightly build (x64 on the build host, arm64 on GitHub's arm64 runner). | ```bash sudo snap install filex-app --edge # a new install, on edge sudo snap refresh filex-app --channel=edge # an installed copy, onto edge sudo snap refresh filex-app --channel=stable # back to the release ``` > ⚠ A nightly build is **not supported**: it is the tip of the source after its > tests passed, nothing more. Its version says which commit it is > (`0.57.0-nightly.20261014+2ca25999`: the next minor, the night, the commit; > `snap info filex-app` lists it). Your settings and the folders you sync are > kept when you move between channels, but a nightly may change them in a way > the release cannot read back: try it on a copy of your data, not the only > one. The same night's desktop packages for Windows, macOS and Linux are on > [filex.sh/nightly](https://filex.sh/nightly/), and the server side has > nightly images too: [Installation → Nightly builds](INSTALLATION.md#nightly-builds). ### On a phone or a tablet: the web app There is no desktop app for a phone: on Android, an iPhone or an iPad, filex is the web app, which installs like an app - an icon on the home screen, a window of its own with no address bar (the manifest's `standalone` display), and its notifications. An instance with its own branding installs under its own name and accent colour, with its logo as the icon when the logo is a picture (uploaded, or at a public address), so two filex servers on one phone are two apps you can tell apart ([The installed app](CONFIGURATION.md#the-installed-app-pwa)). Where a computer is offered the desktop app, a phone gets a band at the bottom of the sign-in page and the file list (which makes room for it) offering the web app; a phone is never offered the desktop app. On a branded instance the band and the settings row say the instance's own name where the steps below say filex, and the band shows the icon the home screen will get. - **Android** (Chrome, Edge, Samsung Internet): **Install filex as a web app → Install** opens the browser's own install dialog. A browser offers that only once it judges the site worth it (Chrome: a tap and about 30 seconds on the site, on any visit); until then the band names the menu item (*Install app* or *Add to Home screen*), and it becomes the **Install** button the moment the browser offers one. Firefox never offers it to a page, so there the menu's way stays. - **iPhone and iPad** (iOS 16.4 or later, any browser): no browser offers an install to a page, so the band says how: **Share** (on iOS 26: **⋯** first) → **Add to Home Screen** → **Add**. On iOS 26 leave **Open as Web App** on, or the icon opens a Safari tab, which cannot show notifications. - **×** on the band closes it for good, on every device you sign in on; the desktop app's reminder on a computer is a separate one. The offer stays in the account menu's **User settings → Preferences → This device → Install as a web app** while the browser can install. - **Once installed**, nothing is offered on that device, in the installed app or a browser tab (the browser stops offering it, and filex remembers the install in that browser until the browser offers it again). **Notifications on a phone.** While filex is open - a tab or the installed app - a new row in the bell raises a notification once you allow it in **User settings → Notifications → This device** ([browser notifications](NOTIFICATIONS.md#browser-notifications)). With filex closed, **Push notifications on this device** in the same pane carries them on ([Web Push](NOTIFICATIONS.md#web-push)). On an iPhone or iPad both work only in the app added to the Home Screen (iOS 16.4 or later), never in a Safari tab, and the permission is asked there, from that button. ## Signing in You are **not** asked for a password in the app. It opens your server's own login page in your browser, and your browser hands back a one-time code - so Keycloak, OIDC, passkeys, MFA and corporate SSO work exactly as they do on the web, often on a session your browser already has (a login form inside the app could only take a username and password). 1. Type your server address (e.g. `https://files.example.com`, or `https://example.com/filex` for a filex [served under a sub-path](DEPLOYMENT.md#serving-filex-under-a-sub-path) - every request the app makes keeps the path). An address pasted from the browser's address bar works too: the page part (`/admin/login`, `/drive/explore`) is dropped, the server's own path is not. 2. Your browser opens; sign in however that server expects. 3. The browser hands the app a one-time code and you are in. **If nothing opens, or the browser cannot get back to the app** - a locked-down machine, a portable browser the OS has no handler for, or you finished signing in on your phone - the waiting screen shows a copyable address, and the browser shows a code you can type into the app by hand. **If a sign-in fails, you stay where you were.** A sign-in link from an earlier attempt, or a code the server refuses, leaves the app on the waiting screen of the current attempt - address and code box still there - with what happened written under them. A refused code cannot be used again (so a code cannot be guessed by repeating), and **Start again in the browser** begins a new attempt for the same server. Clicking the tray or Dock icon, or starting the app again while it waits, keeps that screen too. **Cancel** is the one way back to the server address. **A server with a self-signed certificate.** The app checks the server's certificate against the system's store, so the way that keeps the check on is to trust that certificate on this computer. Where that is not an option, open **Advanced** under the address and tick **Skip certificate verification (insecure)** before you start: your browser asks about the same certificate on its own. It belongs to that account, and *App settings → Accounts* has the same switch on every account. > ⚠ **Not safe, and not recommended.** Anybody who can get between this computer > and the server can pose as it: read and change what crosses, and take your > session. Apply it only if you know what you are doing. - The sync engine follows the switch at once. The window keeps the answer it already gave for that server until filex restarts, in both directions, and Settings says so and offers **Restart now**. A certificate let through stays let through until then. - If a sign-in was refused for the certificate, ticking the box needs that restart too: the app says so before it opens the browser. - It holds for the host, not the address: a second filex on another port of the same machine goes unchecked too. - It does not reach *Mount as a drive*: that is the operating system's own WebDAV client, which judges the certificate itself ([below](#mounting-the-server-as-a-drive)). Add more accounts with **+** on the left rail; switch between them by clicking. **Signing in again** to the same server as the same person (with **+**) replaces that account's credential and keeps everything else - its synced folders, its filex folder, its place on the rail - and its sync restarts with the new credential. **Sign out** (*App settings → Accounts*) forgets the account on this computer and stops its sync at once; the files stay where they are, on both sides. Signing in afterwards makes a new account here, and you keep its folders again from the explorer. To get a working credential back, use **Reconnect** (below) instead. ### Signed out by the server When the server stops accepting this computer's credential - an admin revoked the token, or it expired - the app stops asking: the account's sync stops (the engine exits instead of retrying every 30 seconds), its bell is no longer polled, and it stays that way after a restart. You are told once, with a notification; the rail shows a red dot on the account, and its file view reads **Signed out of <server>** with two buttons: - **Reconnect** opens the same browser sign-in for the same server. Sign in as the same person and the account gets its new credential and keeps its synced folders and its filex folder; sync picks up where it stopped. The same button is on the account in *App settings → Accounts*. - **Sign out** forgets the account, as above. ### The token the app is given Signing in gives the app a **personal** API token (kind `user`, see [MCP.md → Token kinds](MCP.md#token-kinds---user-vs-app)) that acts as you: its scopes are `read,write,delete`, or `read,write` for a **viewer** account - never `admin`. It appears in your token list as *filex desktop - <platform>*; revoking it there signs that copy of the app out. It also carries **`comments:rw`**, so the app reads, adds and deletes comments as the browser does (the account's own `comments.write` still decides). Other API keys and agents' tokens hold comments only at `read` unless given more ([RBAC.md → Permissions with a level](RBAC.md#permissions-with-a-level-comments)); the desktop pairing is the one token minted with it unasked. The token's **Actions → Comments: read only** on the API keys page in your browser makes that desktop read comments only. A viewer's desktop carries `write` because changing the account itself - the profile, the password, two-factor - needs a token's `write` ([RBAC.md → API tokens](RBAC.md#api-tokens-verbs-on-every-surface)), so its account menu saves what the web app saves. It changes no file: the viewer role still refuses every write, link and grant, and the API keys page still mints only `read` for a viewer. Only your **signed-in browser session** can finish the pairing. `POST /api/auth/desktop/complete` answers `403` with `reason: "session_required"` to any API token of either kind, and mints nothing - so no token can mint a wider one for its owner, or turn an integration's token into a person's. **Pairings from older versions are not converted on upgrade:** - **Made before 0.43.0, it holds an `app` token**: the window answers `403` (`app_token`) on its API keys, S3 keys, SSH keys and NFS exports panels, and the explorer hides **Recent**, **Starred** and **Shared with me**. **Sign in again** to the same server as the same person (with **+**; the account keeps its synced folders), then revoke the old *filex desktop* entry on the API keys page in your browser - the app forgets the old token, but nothing revokes it on the server. Or an admin hands the existing token back to its person with no new sign-in (the command below). - **A viewer's pairing made before 0.49.0 holds a `read` token**: its account menu answers 403 on a save until the app signs in again - **Reconnect** on the account in *App settings → Accounts*. ```bash curl -X PATCH https://files.example.com/api/admin/ai-tokens/42 \ -H 'Content-Type: application/json' -b cookies.txt -d '{"kind":"user"}' ``` --- ## Opening and previewing files **Office documents open in the app**, in the editor the web app uses: the Office editor app, or ONLYOFFICE when your server has a Document Server ([Office editing](ONLYOFFICE.md)). **Each document opens in its own window**, one per document, titled with the file's name; the explorer window stays where it is, and the documents are separate windows in the taskbar. **Single click or double click.** By default a single click **selects** and a double click **opens** (Enter opens the selection), as in a desktop file manager; **User settings → Preferences → This device → Open files with** (the avatar) switches between *Double-click* and *Single-click* - for this computer. A touchscreen tap always opens, and the checkbox always selects. **Open in new tab** opens the file in your **browser**, on your server's own editor page (`/files/edit`): the app has no browser tab, so the link is resolved against your server, not the app's internal `app://filex` origin. **Images, video, audio and downloads** work as they do on the web. A ``, `