ws-scrcpy is a free, open source browsers & extensions project written in TypeScript and released under MIT. It has 2,563 GitHub stars, 572 forks and 91 open issues, and was last pushed 9 days ago. On this registry it ranks #93 of 135 tracked projects in Browsers & Extensions, with 5 head-to-head comparisons available.

What is ws-scrcpy?

ws-scrcpy is an MIT-licensed TypeScript web client that mirrors and controls Android devices from a browser, built for developers and testers who want scrcpy-style device access without a native desktop client.

What it is

ws-scrcpy is a browser front end for [Genymobile/scrcpy][scrcpy] and related tooling. A modified version of scrcpy runs on the server side and streams H264 video over WebSockets; the browser decodes that stream with one of four bundled players and sends input events back to the device. It lives in the Android tooling ecosystem alongside adb, and turns a machine with adb in its PATH into a device-hosting server reachable from any modern browser on the network.

The concrete problem it solves: scrcpy itself is a desktop application, so viewing and controlling a device requires a workstation with the phone physically attached and the client installed. ws-scrcpy replaces that desktop client with a browser tab, and it also folds in work that would otherwise need separate tools — pushing APKs, running adb shell, browsing device files, and debugging WebViews. The device stays plugged into one server; the people who need it open a URL.

Key capabilities

  • H264 screen casting with four switchable decoders: the Mse Player (based on xevokk/h264-converter, needs Media Source API and video/mp4; codecs="avc1.42E01E" support), the Broadway Player and TinyH264 Player (WebAssembly software decoders), and the WebCodecs Player, which uses the browser's built-in media decoder and is currently Chromium-only.
  • Remote control covering touch and multi-touch, with CTRL to start multi-touch at screen centre and SHIFT + CTRL to start at the current point, plus mouse wheel and touchpad scrolling, keyboard event capture, ASCII-only text injection, clipboard copy to and from the device, and device rotation.
  • A remote shell that runs adb shell inside the browser.
  • File push by dragging and dropping an APK into /data/local/tmp, which can then be installed manually from the bundled xtermjs/xterm.js terminal emulator.
  • File listing with drag-and-drop upload and download.
  • WebView and web page debugging, documented in /docs/Devtools.md.
  • Experimental iOS screen casting requiring ws-qvh in PATH, with iOS control provided by appium/WebDriverAgent and an alternative MJPEG path gated behind USE_WDA_MJPEG_SERVER. That MJPEG server is temporarily suspended and planned for restoration in a follow-up.

Who uses it and how

  • Teams that keep Android devices attached to a shared host: Node.js runs the server with adb in PATH, and users connect browsers over WebSockets to that host instead of passing hardware around.
  • Developers investigating WebViews and web pages on a device, using the Devtools workflow described in /docs/Devtools.md.
  • Testers installing builds by dragging an APK into the browser session and running the install from the built-in terminal.
  • iOS testers willing to build with the experimental feature enabled, running ws-qvh, connecting the iPhone directly without a USB hub, setting Auto-Lock to Never, and avoiding a standalone ws-qvh/qvh capture against the same device.

Getting started

Clone the repository, run npm install, then npm start; for a stable version, list tags with git tag -l and check out the latest vX.Y.Z first. Node.js v10+, node-gyp with build tools, and an adb executable in PATH are prerequisites.

How it compares

No list of paid or commercial products is given in these facts, so the comparison belongs among the tools it names. It sits between Genymobile/scrcpy, whose native client it reimplements in a browser, and iOS-side tools such as ws-qvh for capture and appium/WebDriverAgent for control, which it drives rather than replaces.

When to use it — and when not to

A self-hoster must run a Node.js server with node-gyp and build tools installed, keep adb in PATH, and have a browser that supports WebSockets, Media Source Extensions with H264 decoding, WebWorkers, and WebAssembly. Skip it if a managed hosted service is wanted, if the fleet is iOS-only, or if non-ASCII text injection is required, since injection is ASCII-only and the iOS path is experimental, not built by default, with its MJPEG video route currently suspended.

project readme (upstream, from github) — read inline

ws scrcpy

Web client for [Genymobile/scrcpy][scrcpy] and more.

Requirements

Browser must support the following technologies:

  • WebSockets
  • Media Source Extensions and h264 decoding;
  • WebWorkers
  • WebAssembly

Server:

  • Node.js v10+
  • node-gyp (installation)
  • adb executable must be available in the PATH environment variable

Device:

Build and Start

Make sure you have installed node.js, node-gyp and build tools

git clone https://github.com/NetrisTV/ws-scrcpy.git
cd ws-scrcpy

## For stable version find latest tag and switch to it:
# git tag -l
# git checkout vX.Y.Z

npm install
npm start

Supported features

Android

Screen casting

The modified [version][fork] of [Genymobile/scrcpy][scrcpy] used to stream H264-video, which then decoded by one of included decoders:

Mse Player

Based on [xevokk/h264-converter][xevokk/h264-converter]. HTML5 Video.
Requires [Media Source API][MSE] and video/mp4; codecs="avc1.42E01E" [support][isTypeSupported]. Creates mp4 containers from NALU, received from a device, then feeds them to [MediaSource][MediaSource]. In theory, it can use hardware acceleration.

Broadway Player

Based on [mbebenita/Broadway][broadway] and [131/h264-live-player][h264-live-player].
Software video-decoder compiled into wasm-module. Requires [WebAssembly][wasm] and preferably [WebGL][webgl] support.

TinyH264 Player

Based on [udevbe/tinyh264][tinyh264].
Software video-decoder compiled into wasm-module. A slightly updated version of [mbebenita/Broadway][broadway]. Requires [WebAssembly][wasm], [WebWorkers][workers], [WebGL][webgl] support.

WebCodecs Player

Decoding is done by browser built-in (software/hardware) media decoder. Requires [WebCodecs][webcodecs] support. At the moment, available only in Chromium and derivatives.

Remote control
  • Touch events (including multi-touch)
  • Multi-touch emulation: CTRL to start with center at the center of the screen, SHIFT + CTRL to start with center at the current point
  • Mouse wheel and touchpad vertical/horizontal scrolling
  • Capturing keyboard events
  • Injecting text (ASCII only)
  • Copy to/from device clipboard
  • Device "rotation"
File push

Drag & drop an APK file to push it to the /data/local/tmp directory. You can install it manually from the included [xtermjs/xterm.js][xterm.js] terminal emulator (see below).

Remote shell

Control your device from adb shell in your browser.

Debug WebPages/WebView

/docs/Devtools.md

File listing
  • List files
  • Upload files by drag & drop
  • Download files

iOS

Experimental Feature: is not built by default (see custom build)

Screen Casting

Requires [ws-qvh][ws-qvh] available in PATH.

Tips for a stable QuickTime-over-USB stream: set the device's Auto-Lock to Never (a locked screen stops the stream), connect the iPhone directly (no USB hub), and do not run a standalone ws-qvh/qvh capture against the same device while ws-scrcpy is streaming — only one process may hold a device.

MJPEG Server

⚠️ Temporarily suspended. After the migration to a standalone Appium (see Remote control) the WDA-MJPEG video path is not wired up and is planned to be restored in a follow-up. iOS screen casting currently runs via ws-qvh (see above).

Enable USE_WDA_MJPEG_SERVER in the build configuration file (see custom build).

Alternative way to stream screen content. It does not require additional software as ws-qvh, but may require more resources as each frame encoded as jpeg image.

Remote control

Device control is provided by [appium/WebDriverAgent][WebDriverAgent], driven through a modern [Appium][appium] server over the W3C WebDriver protocol. ws-scrcpy bundles Appium (it is a dependency, and a postinstall step pins the XCUITest driver into a project-local .appium-home), spawns it as a child process on startup, and forwards control commands to it over HTTP — no global Appium installation is required.

Supported actions:

  • Simple touch
  • Scroll / swipe
  • Home button click
One-time device setup (real iOS device)

WebDriverAgent has to be built, signed and trusted on the device once:

  1. Open the WDA project in Xcode — WebDriverAgent.xcodeproj under .appium-home/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent/ (or under $APPIUM_HOME/… if you point Appium elsewhere). Select the WebDriverAgentRunner scheme, set your Team and a unique Bundle Identifier, and run it on the device once (⌘U).
  2. On the device: trust the developer certificate (Settings → General → VPN & Device Management) and enable Developer Mode (Settings → Privacy & Security → Developer Mode, iOS 16+).
  3. (Optional) enable AssistiveTouch: Settings → General → Accessibility.

See Appium's [real-device configuration guide][wda-real-device] for the full WebDriverAgent setup. After this one-time step ws-scrcpy builds and launches WDA on its own.

Be patient on the first control action. Appium builds and launches WebDriverAgent on demand, which can take a couple of minutes the first time — the screen may look unresponsive until WDA is up. A free Apple developer account's provisioning expires every 7 days (re-sign weekly); a paid account avoids this.

iOS control configuration (environment variables)
Variable Purpose
WDA_TEAM_ID Apple Team ID used to sign WebDriverAgent (the certificate's OU)
WDA_SIGNING_ID Signing identity (default Apple Development)
WDA_BUNDLE_ID Unique WDA bundle id, e.g. com..WebDriverAgentRunner
WDA_PLATFORM_VERSION iOS version of the device (silences a driver warning)
WDA_USE_PREBUILT true to reuse an already built/installed WDA (skip the rebuild)
WS_SCRCPY_DEBUG Verbose logs — surfaces the Appium (incl. xcodebuild) and ws-qvh output in the server console
APPIUM_BIN / APPIUM_HOME / APPIUM_PORT / APPIUM_LOG_LEVEL Override the bundled Appium binary, driver home, port or log level

xcodebuild failed with code 65 almost always means WebDriverAgent could not be signed or launched on the device (untrusted certificate, Developer Mode off, wrong Team ID, or expired provisioning) — it is not a build error in ws-scrcpy. Run with WS_SCRCPY_DEBUG=1 to surface the underlying xcodebuild error and follow the [real-device configuration guide][wda-real-device].

Custom Build

You can customize project before build by overriding the default configuration in build.config.override.json:

  • INCLUDE_APPL - include code for iOS device tracking and control
  • INCLUDE_GOOG - include code for Android device tracking and control
  • INCLUDE_ADB_SHELL - remote shell for android devices ([xtermjs/xterm.js][xterm.js], [Tyriar/node-pty][node-pty])
  • INCLUDE_DEV_TOOLS - dev tools for web pages and web views on android devices
  • INCLUDE_FILE_LISTING - minimalistic file management
  • USE_BROADWAY - include Broadway Player
  • USE_H264_CONVERTER - include Mse Player
  • USE_TINY_H264 - include TinyH264 Player
  • USE_WEBCODECS - include WebCodecs Player
  • USE_WDA_MJPEG_SERVER - configure WebDriverAgent to start MJPEG server (temporarily suspended, see MJPEG Server)
  • USE_QVH_SERVER - include support for [ws-qvh][ws-qvh]
  • SCRCPY_LISTENS_ON_ALL_INTERFACES - WebSocket server in scrcpy-server.jar will listen for connections on all available interfaces. When true, it allows connecting to device directly from a browser. Otherwise, the connection must be established over adb.

Run configuration

You can specify a path to a configuration file in WS_SCRCPY_CONFIG environment variable.

If you want to have another pathname than "/" you can specify it in the WS_SCRCPY_PATHNAME environment variable.

Configuration file format: Configuration.d.ts.

Configuration file example: config.example.yaml.

Known issues

  • The server on the Android Emulator listens on the internal interface and not available from the outsid

readme truncated — read the full docs on github

Frequently asked questions

Is ws-scrcpy free to use?

ws-scrcpy is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does ws-scrcpy do?

Web client prototype for scrcpy.

What is ws-scrcpy written in?

ws-scrcpy is primarily written in TypeScript. Its source is publicly available at https://github.com/NetrisTV/ws-scrcpy, and it has 2,563 GitHub stars.