Your home drive, on every screen in the house.
No cloud, no subscription, no account.
Host for Windows · Host for Linux · Basalt for Windows · Basalt for Android
basalt.reforatech.com · Docs · Release notes · Refora Technologies
Basalt by Refora Technologies turns one computer into a private drive for the whole household. Basalt Host runs on the computer with the drive: Windows or Linux, with a screen or without one, such as a home server, a NAS or a Raspberry Pi. Basalt runs everywhere else, on Windows computers and on Android phones and tablets. Every device browses the same files, watches the same library, and picks up where the last one left off.
There is nothing to configure. You choose a drive on the host; on another device you choose the host from a list and type the PIN it shows. That is the whole setup. No address is ever typed and no account is made. Devices find the host by themselves, and keep finding it when the router gives it a different address, because they recognise the host itself rather than where it happens to be today.
Nothing leaves your home. There is no Basalt server and no cloud in the design: the host serves your files to your devices over your own network, encrypted, and that is all it does.
![]() |
![]() |
| The player: streamed from the drive, every format, every subtitle track | Photos from every folder, by month, at their own shape |
Basalt for Android: the same drive, library and profiles, laid out for touch
Basalt Host: the shared drive, a new device asking to join, and everyone connected
- Finds itself. The host announces itself on your network and every device lists what it finds. If a network blocks that, a device can be given the host's address instead.
- Nobody joins without your say-so. A new device shows a PIN to type, once. After that it simply connects, and the host can make any device read only or remove it.
- Manage it from your phone. Let a device manage the host, and it can do everything the host's own window does: choose or rename the drive, browse the host's folders to share one, let devices in, add profiles and change settings.
- Hosts with no screen. On a server, a NAS or a Raspberry Pi, Basalt Host runs as a background service or in Docker. It shows a one-time setup code; the first device to type it manages the host from then on.
- A drive that comes and goes. Unplug the host's drive and every device says so; plug it back in and it is shared again, with nothing to redo.
- Keeps itself up to date. The host installs new versions by itself when nothing is playing, and the apps show what changed before they update. Every download is checked against its published checksum first.
- Encrypted, and sure of the host. Every connection is encrypted, and each device remembers the host it paired with, so a different computer at the same address is refused rather than trusted.
- A key for every device. Each device signs in with its own key, created on the device and kept in its security chip when it has one. It never leaves the device, so a copy of its settings can't open your drive.
- Local only. No account, no cloud, no tracking. Files travel between your own devices and nowhere else. The only requests that leave your network are the update check, to GitHub, and poster lookups if you turn them on.
- Careful with what it keeps. Profile PINs are stored only as slow, salted hashes, and repeated wrong guesses lock a profile for longer each time.
- Browse everything. Files, folders, search, copy, move, rename, delete, and select several by dragging a box around them.
- Upload the easy way. Drop files or whole folders onto the folder you want. On a phone, upload from the gallery, any file or a folder, or share to Basalt from any other app.
- Fast and checked. Transfers are compressed where that helps, batched for small files, and checked end to end so every file arrives exactly as it was.
- Live. A file added, renamed or deleted on the host, by Basalt or anything else, reaches every connected device at once.
- Recognised automatically. Turn it on and the host files the films and series on the drive under Movies and TV Series, with seasons and episodes in order, and new ones the moment they are copied in. Every film is checked against a bundled catalogue of released titles, offline, so screen recordings and home videos stay out of Movies.
- Posters and picture quality. Optional posters need no API key. Films, series and episodes are tagged HD, Full HD, 2K or 4K from the video itself, not from its file name.
- Continue watching. Resume points live on the host, so a film started on the laptop finishes on the phone, and episodes play on to the next one.
- Photos, music and home videos. The host finds every photo, song and video on the drive, however deep, and sorts each into its own section. Photos are laid out by month at their own shape with a viewer that zooms; music is a track list by artist and album that plays on; videos show a picture from inside them. Thumbnails are made once, on the host, and shared by every device.
- Choose what devices show. The host decides which sections appear on your devices. Hiding one only tidies the list; every file is still in Files.
- Plays what a browser cannot. Built on mpv, on Windows and Android alike, so HEVC, HDR, E-AC3, DTS, MKV and the rest play straight from the drive, with nothing downloaded first.
- 4K on any phone. When a device cannot keep up with a film, the host converts it to 1080p as it plays, on its graphics where it has them, with the sound and subtitles untouched. The player says so while it prepares, picks the film up again if the connection drops, and a quality button switches back to the original at any time. The host measures how many films its computer can convert at once, and converting can be switched off.
- Subtitles done properly. Tracks named by language, remembered on or off from one video to the next, found anywhere on the drive by the film's or episode's name or dropped onto the video, and nudged into sync when they drift.
- Made for the keyboard. Space to pause, arrow keys to seek and change
volume,
Cfor subtitles, Shift+P and Shift+N for the previous and next episode, and,and.to step one frame at a time. Pausing shows what is playing and what comes next.
- Everyone gets their own. A profile is a name, a colour and a PIN. Its Continue watching and starred files follow it to every device, and "keep me signed in" means typing the PIN once per device.
- Or skip it. Carry on as the device, with a history of its own.
- Managed from the host. See who is signed in where, reset a forgotten PIN, or remove a profile along with its history.
- Bring your profile. A profile made on one drive can be used on another host too, once someone who manages that host lets it in. Its PIN stays on its own drive.
- The same app, laid out for touch. Tabs along the bottom on a phone and a rail down the side on a tablet; tap to open, long-press to choose several.
- Films in your hand. Full screen, turned to suit the picture, with a double tap either side to skip. Or hand the stream to another player such as VLC.
- Photos by touch. Pinch to zoom, swipe to the next, swipe down to put it away.
- Carries on with the screen off. A transfer or a song keeps going while the phone is locked, and downloads land in the phone's Download folder.
- Stays on the Wi-Fi. On a Wi-Fi network without internet access, where a phone would normally switch to mobile data, Basalt keeps its connection to the host.
There is no device limit and no connection limit. The host serves bytes and nothing more, so more viewers cost it almost nothing.
| Part | Built with |
|---|---|
| Host and client cores | Rust 2024, Tokio |
| Transport | TCP, TLS 1.3 (rustls + ring), SPKI pinning, custom binary protocol |
| Discovery | UDP beacon on the local network |
| Desktop apps | Tauri v2, React 19, TypeScript, Tailwind, Framer Motion |
| Android app | Tauri v2 mobile, the same React interface, a Kotlin plugin |
| Playback and thumbnails | libmpv, on Windows and Android |
| Film recognition | A bundled catalogue of film and series titles from Wikidata |
| Integrity | BLAKE3 per transfer, SHA-256 on updates |
Download the latest version. These links always give the newest release, and
each file has a .sha256 beside it on the
releases page
if you want to check what you downloaded.
Basalt, on every device that should reach the drive:
| Download | Install on |
|---|---|
Basalt-Client-Setup.exe |
Windows computers |
Basalt-Android.apk |
Android phones and tablets (Android 8.0 or later, 64-bit) |
| Basalt for Linux | Coming soon. Until then, open a Linux host's drive from Windows or Android |
Basalt Host, on the computer with the drive:
| Download | Install on |
|---|---|
Basalt-Host-Setup.exe |
Windows |
Basalt-Host-Linux-amd64.deb |
Ubuntu 22.04 or later, Debian 12, Linux Mint 21 or later |
Basalt-Host-Linux-x86_64.rpm |
Fedora and similar |
Basalt-Host-Linux-x86_64.AppImage |
Any other Linux desktop |
Basalt Host with no screen, for a home server, a NAS or a Raspberry Pi:
| Download | Install on |
|---|---|
Basalt-Host-Server-Linux-amd64.deb |
Debian 11 or later, Ubuntu 20.04 or later |
Basalt-Host-Server-Linux-arm64.deb |
Raspberry Pi OS (64-bit) and other ARM boards |
Basalt-Host-Server-Linux-x86_64.rpm, aarch64.rpm |
Fedora, Rocky and similar |
Basalt-Host-Server-Linux-x86_64.tar.gz, aarch64.tar.gz |
Anything else, installed by hand |
With Docker, for a NAS or a home server (amd64 and arm64):
docker pull ghcr.io/refora-technologies/basalt-host:latestThe compose file and settings are in docker/README.md. Every image is
signed and carries a record of the workflow that built it, which
gh attestation verify oci://ghcr.io/refora-technologies/basalt-host:latest --owner refora-technologies
checks.
The Windows installers install per user and need no administrator rights. They update an existing installation in place and keep its pairing and settings.
The Android app is not on the Play Store yet. Open the .apk on the phone and
allow your browser or file manager to install it when Android asks; that
permission is only for installing, and can be turned off again afterwards.
Getting started:
- Install Basalt Host on the computer with the drive, open it, and choose the drive to share.
- Open Basalt on another device. It lists the host; choose it.
- Type the PIN the host shows. Done.
With no screen: install the package, for example with
sudo apt install ./Basalt-Host-Server-Linux-amd64.deb. It finishes by showing
the host's address and a setup code. Open Basalt on your phone or computer,
choose the host marked new, and type the code. That device then manages the
host: choose what it shares in Manage host. Run sudo basalt-host status
to see it all again; the full guide is in
packaging/linux/README.md.
Step-by-step guides for every kind of host, pairing, the library, the player, profiles, Manage host and troubleshooting are in the docs.
Basalt Host updates itself when nothing is playing; you can turn that off in its settings or in Manage host. The apps check for updates on their own and show what is in the new version before you install it. On Android the update is downloaded, checked against its published checksum, and handed to Android's own installer; the first time, Android asks you to allow Basalt to install it.
Everything Basalt keeps lives in %APPDATA%\Basalt\ on Windows,
~/.config/basalt/ on a Linux desktop, and /var/lib/basalt-host/ for the
host with no screen:
| File | What it is |
|---|---|
host.json |
The host's identity, settings, paired devices and profiles |
client.json |
The drive this device is paired with |
host.log |
The host's log, replaced at each start |
library-*.json, collections-*.json |
The media index, rebuilt by a scan |
watched-*.json, stars-*.json |
Watch history and starred files, per device and per profile |
resolutions-*.json |
Each video's measured picture size |
thumbs/, art/ |
Thumbnails, and downloaded posters |
Deleting host.json regenerates the host's identity, which un-pairs every
device and removes its profiles. The rest can be deleted freely and is
rebuilt as needed, apart from watch history and stars.
On Android the app keeps what it needs in its own private storage, which is left out of phone backups, so its pairing never travels to another device. Clearing the app's storage, or Forget this drive under More, means pairing again.
Optional, and off by default: recognising films and series reads the whole drive, and downloading posters sends the titles of recognised films and series to an online service to find their posters. Neither happens until you turn it on, in Basalt Host or in Manage host.
rustup toolchain install stable # Rust 1.98+ MSVC
cd apps/client/src-tauri && pwsh -File fetch-libmpv.ps1
cd apps/host/src-tauri && pwsh -File fetch-libmpv.ps1 && pwsh -File fetch-ffmpeg.ps1
cd apps/client && npm install && npx tauri build
cd apps/host && npm install && npx tauri build
fetch-libmpv.ps1 downloads libmpv and a small wrapper into src-tauri/lib/
and verifies the wrapper's checksum. They are not in the repository because
libmpv-2.dll is 96 MB. The host uses the same libmpv to make thumbnails of
videos; its script copies the client's rather than downloading it again.
fetch-ffmpeg.ps1 puts ffmpeg into the host's src-tauri/lib/, checked
against the checksum its builder publishes. The host uses it to convert video
for a device that cannot play a file itself.
The host recognises films against a catalogue of every film and series title
on Wikidata, bundled so that it works offline and sends nothing anywhere. It is
committed at crates/basalt-catalog/data/catalog.bin (about 3 MB) and rebuilt
for each release with:
cargo run -p catalog-build --release
cargo test --all runs the Rust suite; npm test in either app runs its own.
On Linux with Docker:
packaging/build-desktop-linux.sh OUT_DIR # Basalt Host with a window: .deb, .rpm, AppImage
packaging/build-server.sh OUT_DIR # with no screen: .deb, .rpm, .tar.gz, amd64 and arm64
docker build -f docker/Dockerfile -t basalt-host .
Each builds inside an older system's container, so what it makes runs on Ubuntu 22.04, Debian 11 and everything newer.
It needs the Android SDK with NDK 28, JDK 17, and Rust's Android targets:
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android
set NDK_HOME=%LOCALAPPDATA%\Android\Sdk\ndk\28.2.13676358
set JAVA_HOME=C:\Program Files\Java\jdk-17
cd apps/client && npx tauri android build --apk --target aarch64
The phone's player is mpv too, from the dev.jdtech.mpv:libmpv package, which
Gradle fetches by itself; the desktop's Windows libraries are left out.
Release builds are signed with a key kept outside the repository. Gradle reads
its location and passwords from
%USERPROFILE%\.basalt\android-signing\keystore.properties, or from the file
BASALT_SIGNING names:
storeFile=D:/path/to/basalt-release.keystore
storePassword=...
keyAlias=basalt
keyPassword=...
Without it the build is left unsigned. Keep the key safe: Android installs an update only over an app signed with the same key.
npx tauri android build --debug --apk --target x86_64 builds for the
emulator. After regenerating icons with npx tauri icon, run
python tools/make-icons.py again so the Android project has its own.
- Questions and help: Help and setup
- Ideas and votes: Ideas
- Show your setup: Your setup
- Bugs: open an issue
- Security problems: privately, as SECURITY.md explains
- Contributing: see CONTRIBUTING.md
This project is licensed under the GNU General Public License v3.0 (GPLv3).
You are free to use, modify and distribute this software, provided any
derivative works are also open-source under the identical terms. See the
LICENSE file for the complete terms.
Basalt bundles libmpv (LGPL-2.1-or-later) — and, in the Android app, the
libmpv-android build of it — and links a number of open-source libraries. See
THIRD-PARTY-NOTICES.txt for full attribution.
Crafted by Refora Technologies


