# tapflow: self-hosted iOS and Android simulator streaming for mobile QA teams

> tapflow runs a relay server and macOS agents so anyone on the team can drive iOS Simulators and Android emulators from a browser, without Xcode or a cloud device service. The trade-off is that agents only run on macOS.

**jo-duchan/tapflow** — Self-hosted iOS & Android simulator streaming for the whole team. 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.

- Repository: https://github.com/jo-duchan/tapflow
- Website: https://www.tapflow.dev
- Stars: 697 · Forks: 80
- Language: TypeScript
- License: MIT
- Published: 2026-08-04 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/jo-duchan-tapflow

## The access problem tapflow is built around

Mobile QA has an uneven distribution problem. A developer with Xcode or Android Studio on a Mac can open a simulator whenever they want. A backend developer, a product manager or a designer usually cannot, so they ask a mobile developer to install a build, or they install and remove versions on their own phone to compare behaviour. The README frames this with three quoted situations: a backend developer asking how to install a sandbox build, a product manager reinstalling versions to compare behaviour, and a designer checking layout across screen sizes without the right devices.

tapflow's answer is to keep the simulators where they already run, on Macs, and expose them through a browser dashboard. The README's comparison table lists the alternatives and their costs: Appetize and BrowserStack charge recurring fees and require uploading internal builds to a third party; physical devices bring cost, availability, OS coverage and management overhead; Xcode and Android Studio require every teammate to have a Mac and a full mobile toolchain. tapflow's stated position is that you reuse your own Macs and the data stays on infrastructure you control.

The audience is therefore a team, not an individual. A solo developer with a Mac gains little from a relay plus agent architecture when Xcode is already in front of them. The value appears when several people need the same running simulator at different times.

## Relay, agent and dashboard: the three moving parts

The architecture has three components. A self-hosted relay runs on Linux or Mac and also serves the dashboard on the same port, so there is no separate web server to deploy. A macOS agent drives the iOS Simulator and the Android emulator. A browser dashboard is what the rest of the team uses to pick an available device and interact with it.

The connection direction is the design decision worth noting. The agent connects outbound to the relay, which the README says means no inbound firewall rules are needed on the Mac. That matters in office networks where a laptop is not reachable from a server. The README also states that the iOS agent injects touch directly without WebDriverAgent, which removes a dependency that normally has to be built and kept in sync with Xcode versions.

The data flow is drawn in the README as a chain: browser to relay over WebSocket, relay to Mac agent over an outbound WebSocket. Streaming is H.264 through what the README calls a 2-tier decoder, using WebCodecs on secure contexts and WASM/tinyh264 on plain HTTP, with the stated goal of removing the media-element buffer from the decode path. The README claims roughly 30 fps and says resolution adapts to the connection, native on a secure context and downscaled on a plain-HTTP LAN. It also documents a codec fallback to JPEG when neither a hardware nor a WASM decoder is available, which is the reason older browsers still work.

## Installing tapflow and running your first simulator session

The README's quick start is a global npm install. Node.js 22 or newer is required for the relay and the agents, and the package is published as tapflow.

```bash
npm install -g tapflow
# or: yarn global add tapflow  |  pnpm add -g tapflow
```

On the Mac that will run an agent, one command installs the simulator and emulator prerequisites. The README says to skip this step on a relay-only Linux server.

```bash
tapflow setup
```

Then start the relay and the agent together. The README calls this local mode because both processes run on the same Mac, and it shows the expected console output.

```bash
tapflow start
# ✓ Relay started on http://localhost:4000
# ✓ iOS Agent connected (3 simulators available)
```

Open http://localhost:4000 in a browser. The README states that tapflow redirects you to /setup to create the admin account. On a headless server, the CLI equivalent is tapflow admin init. After signing in, the dashboard lists available devices; picking one starts the stream in the browser.

If something is missing, the README points to tapflow doctor, which re-checks prerequisites at any time. The relay needs about 512 MB of RAM according to the requirements table, and the browser side needs nothing beyond a modern Chrome, Firefox, Safari or Edge.

## The macOS-only agent constraint

The requirements table is explicit: agents run on macOS only, because they drive the iOS Simulator and the Android emulator on a Mac. The relay runs anywhere. That single line decides whether tapflow fits your infrastructure.

If your team has no Mac that can stay switched on and reachable, tapflow is the wrong tool. The Android agent does not run on a Linux box even though the Android SDK itself does, so a Linux-only shop cannot use tapflow for Android emulator streaming. The relay being portable does not help, because the relay does not run simulators.

There is a second boundary in the README's "What tapflow is not" section. tapflow is not a device farm, and it does not replace Xcode, Android Studio or build tooling. It also states that wiring in external automation frameworks like WebDriverAgent or Appium is out of scope; tapflow ships its own minimal runner instead. Teams whose test suites are already written against Appium should read that as a deliberate exclusion rather than a gap that will close soon.

The version status is worth reading carefully. The README labels the project v0.x and says backward compatibility is the default, with breaking changes rare and noted in the changelog. The most recent release listed is v0.20.0 on 2026-08-28. Treat a pre-1.0 version line as one where you check CHANGELOG.md before upgrading rather than assuming an upgrade is free.

## How tapflow differs from Appetize, BrowserStack and a plain device lab

Appetize and BrowserStack are hosted services. You upload a build and they run it on their infrastructure, which is why they work from any machine and why the README's objection is that internal builds leave your network and you pay per remote device while your own Macs sit idle. tapflow inverts that: the build never leaves, the compute is hardware you already own, and the cost moves from a subscription to the operational work of keeping a relay and agent Macs running.

A physical device lab is the other real alternative. Devices give you real hardware behaviour, which simulators do not reproduce, and they are not tied to macOS for Android. The README's counterargument is the overhead list: OS-version coverage, availability, charging, storage and handoff. A device lab is the right choice when your testing depends on real sensors, real network conditions or real GPU behaviour. tapflow streams simulators and emulators, so it cannot answer those questions.

Against simply giving everyone Xcode, the difference is provisioning. Xcode requires a Mac and a full mobile toolchain per person. tapflow requires a browser per person and one toolchain on the agent Mac. That is the whole trade: fewer machines to set up, in exchange for a relay and agent processes you now operate.

## Licence, upgrades and the maintenance cost you are taking on

tapflow is MIT licensed, and the repository includes a NOTICE file alongside LICENSE. MIT is permissive: you can run it internally, modify it and redistribute it, provided the copyright notice and permission notice are preserved. That is the extent of what the repository states, and it is not legal advice; if you are embedding tapflow in a product you ship, have your own counsel read the LICENSE and NOTICE files.

The operational cost is the part the README understates. Self-hosting means you own the relay's uptime, the agent Macs' availability, and the network path between them. The relay needs Node.js 22 or newer and roughly 512 MB of RAM, which is modest, but the agent Macs need Xcode and an iOS Simulator runtime, or Java and an Android SDK with an AVD. Those are the same prerequisites you would manage for mobile development, now with a streaming service layered on top.

Upgrade cost depends on the release cadence. Three releases are listed in August 2026: v0.18.0 on 2026-08-03, v0.19.0 on 2026-08-18 and v0.20.0 on 2026-08-28. The last push to the default branch was on 2026-08-28. At that cadence, pinning a version and reading CHANGELOG.md before moving is more sensible than tracking main. The README's promise of backward compatibility by default is a stated intention, not a guarantee you can rely on before 1.0.

## Conclusion

Adopt tapflow if your QA, design and backend teammates already ask mobile developers for simulator access, and you have Macs that can host agents plus a Linux or Mac box for the relay. Skip it if you need Windows or Linux agents, or if your automation already lives in Appium or WebDriverAgent, since the README puts external frameworks out of scope. Before rolling it out, run tapflow doctor on each agent Mac, confirm the relay's Node.js version is 22 or newer, and check whether your team's browsers reach the dashboard over HTTPS or plain HTTP, because that decides whether you get WebCodecs or the WASM decoder.

## FAQ

### Is tapflow legitimate?

It is an MIT-licensed open source project published on npm as tapflow and hosted at github.com/jo-duchan/tapflow, with documentation at tapflow.dev. The README states that everything runs on infrastructure you control, so builds and recordings are not uploaded to a third-party service. The most recent release listed is v0.20.0 on 2026-08-28.

### Does tapflow need WebDriverAgent or Appium?

No. The README states that the iOS agent injects touch directly without WebDriverAgent, and the "What tapflow is not" section says that wiring in external automation frameworks like WebDriverAgent or Appium is out of scope because tapflow ships its own minimal runner.

### Can I run a tapflow agent on Linux?

No. The requirements table says agents run on macOS only, because they drive the iOS Simulator and the Android emulator on a Mac. The relay runs on any OS with Node.js 22 or newer, including Linux.

### What port does the tapflow relay use?

The README's quick start shows the relay started on http://localhost:4000, and the same port also serves the dashboard, so no separate web server is needed. The README does not document changing that port in the quick start.

### How do I create the tapflow admin account on a headless server?

The README says that opening http://localhost:4000 redirects you to /setup to create the admin account in the browser. For a headless server it gives the CLI alternative tapflow admin init.

## Sources

- [Official documentation](https://www.tapflow.dev)
- [Official README](https://github.com/jo-duchan/tapflow#readme)
- [Project repository](https://github.com/jo-duchan/tapflow)
- [Release notes](https://github.com/jo-duchan/tapflow/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jo-duchan-tapflow
