https://github.com/jo-duchan/tapflow
Self-hosted iOS & Android simulator streaming for the whole team
https://github.com/jo-duchan/tapflow
android android-emulators app-development appetize-alternative fultter ios ios-simulators mobile-test mobile-test-automation react-native self-hosting
Last synced: 1 day ago
JSON representation
Self-hosted iOS & Android simulator streaming for the whole team
- Host: GitHub
- URL: https://github.com/jo-duchan/tapflow
- Owner: jo-duchan
- License: mit
- Created: 2026-05-07T15:34:29.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-06-03T16:11:22.000Z (8 days ago)
- Last Synced: 2026-06-03T16:13:28.343Z (8 days ago)
- Topics: android, android-emulators, app-development, appetize-alternative, fultter, ios, ios-simulators, mobile-test, mobile-test-automation, react-native, self-hosting
- Language: TypeScript
- Homepage: https://www.tapflow.dev
- Size: 22.1 MB
- Stars: 33
- Watchers: 0
- Forks: 4
- Open Issues: 18
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Roadmap: ROADMAP.md
- Notice: NOTICE
Awesome Lists containing this project
README
A self-hosted Appetize / BrowserStack alternative for mobile QA teams
Run iOS simulators and Android emulators in any browser โ no toolchain setup, no device pool, no cloud uploads.
Your builds, streams, and recordings stay on infrastructure you control.
๐ Docs
ย ยทย
๐ Quick Start
ย ยทย
๐ฅ Demo
> **v0.x**: tapflow is under active development. Breaking changes may appear in minor versions until v1.0.0. See [ROADMAP](./ROADMAP.md) for the full plan.
---
## Why tapflow?
Mobile QA usually depends on access to simulators, emulators, or physical devices โ and that access is uneven across a team.
For mobile developers it means opening Xcode or Android Studio on a Mac. For everyone else, it often means asking a mobile developer every single time:
> **Backend developer** โ "How do I install the sandbox build to check what was deployed?"
>
> **Product manager** โ "I keep installing and removing versions just to compare behavior."
>
> **Designer** โ "I need to check the layout across screen sizes, but I don't have the right devices."
Physical devices add their own overhead โ OS-version coverage, availability, charging, storage, handoff. Cloud simulator services solve access, but they require uploading internal builds to a third-party service and paying for remote devices while your own Macs can already run the same simulators.
We hit this exact problem, so we built tapflow.
| Solution | The catch |
|----------|-----------|
| Appetize / BrowserStack | Recurring cost โ and app builds are uploaded to a third-party cloud |
| Physical devices | Cost, availability, OS coverage, management overhead |
| Xcode / Android Studio | Each teammate needs a Mac and a full mobile toolchain |
| **tapflow** | Reuse your own Macs โ data stays on infrastructure you control, and the whole team does QA from a browser |
## What tapflow does
tapflow connects three parts:
1. A **self-hosted relay** server (Linux or Mac)
2. A **macOS agent** that drives iOS simulators and Android emulators
3. A **browser dashboard** for the rest of the team
The agent connects outbound to the relay. Teammates open the dashboard, pick an available device, and interact with it remotely โ while the simulators and emulators keep running on your own Macs.
## What tapflow is not
tapflow doesn't replace native mobile development tools. Mobile developers still use Xcode, Android Studio, and their build tooling. tapflow makes the *running* simulators and emulators accessible to the rest of the team through a browser โ it isn't an automation framework or a device farm.
## How it works
```
Browser (your team) โโ WebSocket โโ Relay Server โโ WebSocket (outbound) โโ Mac Agent
(Linux / Mac) (iOS ยท Android)
```
1. The **Mac Agent** connects *outbound* to the relay โ no inbound firewall rules needed.
2. Anyone on the team opens the **dashboard** in any browser and sees all available devices.
3. Touch events are forwarded in real time; the screen streams back to the browser.
4. The **relay** also serves the dashboard SPA on the same port โ no separate web server needed.
## Quick Start
### 1. Install
```sh
npm install -g tapflow
# or: yarn global add tapflow | pnpm add -g tapflow
```
### 2. Start relay + agent
```sh
tapflow start
# โ Relay started on http://localhost:4000
# โ iOS Agent connected (3 simulators available)
```
This starts both the relay and the agent on the same Mac (local mode).
### 3. Create the first admin account
Open `http://localhost:4000` in your browser. tapflow redirects you to `/setup` to create the admin account.
> **Headless server?** Use `tapflow admin init` to create the admin account via CLI instead.
### 4. Open the dashboard
Navigate to `http://localhost:4000` and sign in with the account you just created.
> **Having issues?** Run `tapflow doctor` to auto-diagnose Node.js, the iOS toolchain, `adb`, and other prerequisites.
## Requirements
| Component | Requirements |
|-----------|-------------|
| **Relay server** | Node.js โฅ 20, any OS (Linux/macOS), ~512 MB RAM |
| **iOS Agent** | macOS, Xcode with the iOS Simulator runtime, Node.js โฅ 20 |
| **Android Agent** | macOS, Android SDK (`adb` in `$PATH` or `$ANDROID_HOME` set), an AVD with `google_apis/arm64-v8a` (android-34), Node.js โฅ 20 |
| **Browser (QA)** | Any modern browser โ Chrome, Firefox, Safari, Edge |
> Agents run on **macOS only** (they drive the iOS Simulator and Android emulator on a Mac). The relay runs anywhere.
## Features
- **No mobile toolchain for QA users** โ teammates test from a browser without installing Xcode, Android Studio, or local simulator tooling.
- **Self-hosted by default** โ app builds, device streams, recordings, and account data stay on infrastructure you control.
- **Use your existing Mac setup** โ run agents on Macs that already have the iOS Simulator or Android emulator available.
- **API-first** โ REST endpoints and Personal Access Tokens support CI/CD and AI-agent workflows.
What's included:
- **Browser streaming** โ iOS & Android at ~30 fps, no extra app on the device. Both stream H.264 through a 2-tier decoder (WebCodecs on secure contexts, WASM/tinyh264 on plain HTTP), which removes the media-element buffer from the decode path. Resolution adapts to the connection โ native on a secure context, downscaled on plain-HTTP LAN.[1](#latency-note)
- **Codec fallback** โ the stream negotiates the codec per client and falls back to JPEG when a hardware or WASM decoder isn't available, so older browsers still work.
- **Touch, swipe & pinch** โ real-time input forwarded to the simulator or emulator.
- **Deeplink toolbar** โ open supported deeplinks directly from the QA toolbar.
- **Keyboard shortcuts** โ trigger simulator toolbar actions from the keyboard.
- **App Center** โ upload `.app.zip` / `.apk` and track builds by status (Backlog / In Progress / Done / Rejected).
- **Session recordings** โ record and share QA sessions, kept on the relay for ~72 hours, then purged automatically.
- **Screenshot REST endpoint** โ `GET /api/v1/sessions/:sessionId/screenshot` for CI and AI agents.
- **Mac resource monitoring** โ CPU & RAM per agent, to spot overloaded hosts before assigning sessions.
- **Team management** โ invite links, roles (Admin / Developer / QA / Viewer), and Personal Access Tokens.
- **MCP Server** *(experimental)* โ `@tapflowio/mcp-server` lets Claude Code and other LLM agents control simulators as native tools.
> 1 On a real LAN, decode-to-present measures in the low tens of milliseconds (p50 ~11โ17 ms with the WASM software decoder; faster with WebCodecs on HTTPS); end-to-end "glass-to-glass" latency adds your network's round trip on top. See the [performance & latency reference](https://www.tapflow.dev/reference/performance) for the full measurements, conditions, and known limitations.
## Security & Privacy
tapflow is self-hosted by design โ build files, device streams, and session recordings stay on infrastructure you control, never sent to a third-party service.
| Data | Where it stays |
|------|----------------|
| App binaries (`.app.zip` / `.apk`) | Relay storage |
| Device streams (video ยท touch) | The relay โ browser path you host |
| Session recordings | Relay storage; expire after 72h, then purged |
| Account & team data | The relay's SQLite DB |
| Third-party simulator cloud | Not required |
- **LAN-first** โ the agent โ relay leg is internal traffic; the device stream never transits a third party.
- **PAT + roles** โ Personal Access Tokens carry scopes (e.g. `builds:write` for CI uploads), and team roles (Admin / Developer / QA / Viewer) govern dashboard access.
Found a vulnerability? See [SECURITY.md](SECURITY.md). For the full model, read [Security & Privacy](https://www.tapflow.dev/guide/security).
## Self-Hosting
### Local (single Mac)
Relay and agent on the same machine โ ideal for a single developer or small team.
```sh
tapflow start
```
### Team (separate relay server)
Run the relay on a Linux server or dedicated Mac. Each Mac with simulators runs the agent.
**Relay server:**
```sh
# Recommended: PM2 for automatic restarts
npm install -g pm2 tapflow
JWT_SECRET=$(openssl rand -hex 32) pm2 start tapflow --name relay -- relay start
pm2 save && pm2 startup
```
**Each Mac agent:**
```sh
tapflow agent start --relay wss://your-relay-url
```
> For nginx / Caddy reverse proxy setup and external access, see [Self-Hosting the Relay](https://www.tapflow.dev/guide/self-hosting).
## CLI Reference
| Command | Description |
|---------|-------------|
| `tapflow start` | Start relay + agent together (local mode) |
| `tapflow relay start` | Start relay only |
| `tapflow agent start --relay ` | Start agent and connect to a relay |
| `tapflow init` | Scaffold `tapflow.config.json` |
| `tapflow admin init` | Create the first admin account (CLI fallback) |
| `tapflow doctor` | Diagnose environment (Node, iOS toolchain, adbโฆ) |
| `tapflow devices` | List available simulators and emulators |
| `tapflow boot ` | Boot a simulator or emulator |
| `tapflow status` | Show connected agents, devices, active sessions |
| `tapflow reset` | Shut down all simulators and emulators |
| `tapflow logs` | Show recent relay log entries |
Full reference โ [CLI docs](https://www.tapflow.dev/reference/cli)
## Documentation
**[www.tapflow.dev](https://www.tapflow.dev)**
**Getting Started**
- [Introduction](https://www.tapflow.dev/guide/introduction)
- [Quick Start](https://www.tapflow.dev/guide/getting-started)
- [Requirements](https://www.tapflow.dev/guide/requirements)
**Setup**
- [Self-Hosting the Relay](https://www.tapflow.dev/guide/self-hosting)
- [Security & Privacy](https://www.tapflow.dev/guide/security)
- [Agent Setup](https://www.tapflow.dev/guide/agent)
- [Uploading Builds (CI/CD)](https://www.tapflow.dev/guide/upload-builds)
- [Scaling Mac Resources](https://www.tapflow.dev/guide/scaling)
**Dashboard**
- [First-time Setup](https://www.tapflow.dev/dashboard/setup)
- [Dashboard Overview](https://www.tapflow.dev/dashboard/overview)
**AI Agent**
- [MCP Server](https://www.tapflow.dev/guide/mcp-server) *(experimental)*
**Reference**
- [CLI Reference](https://www.tapflow.dev/reference/cli)
- [Configuration](https://www.tapflow.dev/reference/configuration)
- [REST API](https://www.tapflow.dev/reference/api)
**[Troubleshooting](https://www.tapflow.dev/guide/troubleshooting)**
## Contributing
tapflow is actively developed and PRs are welcome โ see [CONTRIBUTING.md](CONTRIBUTING.md) for branch strategy, commit conventions, and an architecture overview. For deep dives, the [contributor notes](CONTRIBUTING.md#technical-internals) cover the SimulatorKit reverse-engineering and the streaming render pipeline.
**Requirements**: Node.js โฅ 20, pnpm โฅ 9
```sh
git clone https://github.com/jo-duchan/tapflow.git
cd tapflow
pnpm install
pnpm dev
```
## License
[MIT](LICENSE) โ Copyright ยฉ 2026-present tapflow contributors
> tapflow bundles [scrcpy-server](https://github.com/Genymobile/scrcpy) (Apache-2.0) for Android screen streaming. See [NOTICE](NOTICE) for full attribution.