A companion app for the Steam Frame: mirror the headset to your phone, keep an eye on battery, controllers, downloads and what's playing. Demo Video
FrameMate mirrors what the headset shows to your phone. Show your friends what you're doing in VR, guide someone through their first session, or just check what's on screen. The picture is the actual view in the headset, passthrough included. Encoded on using hardware acceleration to keep the load low.
- Headset battery – the same percentage Steam shows in the headset, charging state, time left or time to full, and current power draw.
- Controller batteries – both controllers, including while they sleep (the last known level is remembered across restarts).
- Now playing – the running game with its Steam artwork.
- Downloads – the Frame's download queue with progress, speed and time left, plus recently finished updates. Downloads of your other PCs (Steam Remote Downloads) are left out.
- Mirroring – see above; also available in any browser.
- System – performance profile, CPU/GPU settings, network throughput, SteamOS and Steam client versions, battery temperature and health.
- Web dashboard – a plain-text status page on the Frame for any browser on your network.
- Lightweight – the agent on the Frame is a single static binary (~5 MB, a few MB of RAM) that idles at practically zero CPU.
You need a Steam Frame and an Android phone on the same network.
The agent ships as a Flatpak. Open a terminal on the Frame (Desktop Mode → Konsole, or via SSH) and run:
curl -LO https://github.com/nailuj05/framemate/releases/latest/download/framemate-agent.flatpak
flatpak install --user -y framemate-agent.flatpak
flatpak run dev.framemate.Agent install-service
rm framemate-agent.flatpakflatpak installpulls the Freedesktop runtime from Flathub if it isn't installed yet (about 270 MB, once).install-serviceregisters a user service, so the agent starts with every boot – in Game Mode too – and restarts it right away. It then runs a self check and prints the address and access token (e.g.MCK55-EGGCG) you'll enter in the app.flatpak run dev.framemate.Agent checkrepeats the self check (useful when the app can't connect);flatpak run dev.framemate.Agent tokenprints just the token.
To update, download the new framemate-agent.flatpak and run the same three commands
again. To remove it:
flatpak run dev.framemate.Agent uninstall-service
flatpak uninstall --user dev.framemate.Agent- Download
framemate.apkfrom the latest release on your phone. - Open it and allow your browser/file manager to install apps when Android asks.
- In the app's Settings tab, enter the Frame's address (
frame.local, or its IP) and the token, then tap Save & connect.
If you encounter any issues please check out TROUBLESHOOTING.
With the agent running, http://frame.local:7380/?token=<your token> shows a plain-text status
page in any browser, and http://frame.local:7380/stream?token=<your token> mirroring.
- Unofficial. FrameMate relies on undocumented Steam internals. A Steam or SteamOS update can break parts of it until the agent is updated. Tested on SteamOS 0.4.3 (beta branch).
- Local network only. The agent listens on port 7380 and talks plain HTTP/WebSocket, protected by the token. Don't expose that port to the internet. The connection isn't encrypted, so others on the same network could read the token and what's sent, including Mirroring. Use FrameMate on networks you trust, like your home Wi-Fi, not on public or shared ones.
- Developer Mode. FrameMate doesn't depend on it. Note that while it is on, SteamOS's devkit service exposes Steam's debugging interface to your whole network (port 8081); FrameMate never uses that port.
- Battery percentage. FrameMate shows the percentage Steam shows. The raw value of the battery gauge is lower (Steam scales it), so other tools may report a different number.
Requirements: Rust (with the aarch64-unknown-linux-musl target), Bun, Flatpak, and for the app
the Android SDK + NDK and JDK 21.
# Agent: static aarch64 binary → Flatpak bundle (no flatpak-builder or emulation needed)
rustup target add aarch64-unknown-linux-musl
scripts/flatpak.sh # → target/flatpak/framemate-agent.flatpak
scripts/flatpak.sh install # build, install on the Frame via SSH, register the service
# Development loop: run the current build on the Frame without packaging
scripts/deploy.sh # scripts/deploy.sh logs | stop
# App
cd app
bun install
bun run tauri android build --apk --target aarch64
bun run tauri dev # desktop window for UI workscripts/*.sh reach the Frame as steamos@frame.local (override with FRAME_HOST).
| Endpoint | |
|---|---|
GET /api/state |
full state as JSON |
GET /api/ws |
the same, pushed on every change |
GET /api/stream/ws |
mirroring: {codec} header, fMP4 init segment, one fragment per frame |
GET / · GET /stream |
web dashboard · mirroring player |
Authenticate with ?token=<token> or Authorization: Bearer <token>.
In theory this app should be able to be build for iOS aswell, I do not have the devices or infrastructure to build and test an iOS version. If you do and you want to contribute, please let me know!
Patches and bug reports are welcome — see CONTRIBUTING.md.
Commits need a Signed-off-by line (git commit -s); there's no CLA.
FrameMate is free software under the GNU General Public License v3.0 or
later (LICENSE). You may use, study, share and modify it. If you
distribute it — modified or not, free or for money — you must pass on the same
freedoms and make the complete source available under the same license. Closed
forks are not permitted.
Two additional terms apply, in LICENSE-EXCEPTION.md:
an app store distribution permission under GPL-3.0 §7, and a reservation of the
FrameMate name, logo and application identifiers (forks must use their own).
- iOS Support
- TLS Support (self signed + pinning + QR pairing)
- PWA for the mobile client
- Feed on the App notifying you of newly frame verified games (in your library)
- Control Downloads (pause, resume, reorder)
- Turn off controller, headset, etc.
This project used AI for reversing the Steam API (for use in the agent), the frontend of the mobile app, the shell scripts and the Actions used for building the releases. AI was also used for exploring how the Video Stream for Mirroring could be accessed and encoded.
- Icons: Material Symbols (Apache-2.0); see
app/src/lib/icons/LICENSES.md. - Game artwork is loaded from Steam's public CDN.
- FrameMate Icon made by me
FrameMate is not affiliated with or endorsed by Valve. Steam, SteamOS and Steam Frame are trademarks of Valve Corporation.



