Escrcpy is a pnpm + Turborepo monorepo for an Electron GUI around Android mirroring/control with scrcpy. Keep this file focused on agent-critical facts; link existing docs instead of copying them. For the broader overview, start with develop.md.
- desktop/ is the Electron app. The main process is plugin-based via
@escrcpy/electron-setup; the entry point is desktop/electron/main.js. - Renderer windows are separate Vite entries in desktop/vite.config.js:
main,control,explorer,copilot,terminal,automation, andmirror. - Window modules live under desktop/electron/modules/. Register main-process features as modules/services instead of adding logic to the preload script.
- packages/electron-setup/ provides app/plugin/window management primitives. packages/electron-ipcx/README.md documents IPC with renderer callbacks.
- packages/wscrcpy/ is a self-contained Vue + TS module built from
src/(tsdown + unplugin-vue, declarations via vue-tsc). Two process-scoped entries: the package root exports the renderer-facing API (Wscrcpycomponent, composables, core helpers/types), and@escrcpy/wscrcpy/mainexports the main-process ByteBridge factory — never import the root from main or./mainfrom a renderer.service/bridge/is a thin main-process TCP ⇄ MessagePort pump;src/stack/owns the full protocol stack inside each window;src/core/runtime.tsroutes every wscrcpy channel to the local stack. Preserve the public signatures and theDeviceTarget = 'all' | 'primary' | string | string[]contract; business code stays untouched across internal changes. - packages/madb/ is an MCP server for AI agent Android device control via ADB and yadb (32 tools). See its AGENTS.md.
- packages/adbx/ is an injected adbkit capability layer; it prefers yadb when available and falls back to standard ADB.
- packages/shared/ contains platform-neutral utilities shared across workspace packages.
- packages/unocss-preset-shades/ is an UnoCSS preset that generates color shades from a base color.
- Install:
corepack enable pnpm && pnpm install. - Dev:
pnpm devstarts Turbo-managed app development; the desktop Vite server uses port1535. - Lint:
pnpm lintorpnpm lint:fix. - Build:
pnpm build; platform variants arepnpm build:win,pnpm build:mac, andpnpm build:linux. - Docs:
pnpm docs:dev,pnpm docs:build,pnpm docs:preview. - i18n sync:
pnpm lang-syncafter editing locale keys indesktop/electron/resources/extra/common/locales/*.json. - Electron install repair:
pnpm electron-fixwhen Electron reports an incomplete install. - wscrcpy type check:
pnpm --filter @escrcpy/wscrcpy typecheck(vue-tsc; plain tsc cannot resolve.vueimports).
There is no repo-wide test script today. For changes, run the smallest meaningful verification first, then pnpm lint; use pnpm build for packaging, Electron main-process, Vite config, dependency, or release-sensitive changes.
- Vue code uses Vue 3 Composition API with
<script setup>and auto-imported Vue, VueUse, Pinia, router,definePage, andtglobals from desktop/src/plugins/internal.js and eslint.config.js. - Use existing aliases from desktop/vite.config.js:
$,$root,$docs,$renderer,$electron,$control,$explorer,$copilot,$terminal,$automation, and$mirror. - File-based routes live in desktop/src/views/ and exclude nested
componentsfolders. - Pinia stores live in desktop/src/store/, with persisted state and
window.$preload.storefor electron-store integration. See desktop/src/store/device/index.js for the main pattern. - Styling uses UnoCSS utilities and project presets from desktop/uno.config.js. Prefer local utility/style patterns over introducing new UI systems.
- Use regular
ipcRenderer.invoke/ipcMain.handlefor simple request-response channels. - Use
ipcxRenderer.invokeandipcxMain.handlefrom@escrcpy/electron-ipcxwhen callbacks or functions must cross the renderer-main boundary. - Keep preload exposure minimal and routed through existing middleware; renderer code should use
window.$preloadsurfaces rather than importing Electron main-process modules. - External binary paths for scrcpy, adb, and gnirehtet are resolved through desktop/electron/configs/which/ with electron-store/user-path fallbacks. Do not hardcode platform paths.
- Locale JSON is stored in
desktop/electron/resources/extra/common/locales/*.json;zh-CNis the primary language for sync. - Main-process i18n uses
i18next-fs-backend, exposes helpers through preload, and renderer translation uses the globalthelper. - After adding or renaming translation keys, run
pnpm lang-syncand check both Chinese and English strings.
- In
desktop/electron/middleware/scrcpy, never resolve a ready Promise with the scrcpy process object directly. It is thenable-like and Promise resolution can adopt it, causingresolveOnReadyto hang; resolve with plain data orundefined. - Turbo disables caching for Electron packaging in turbo.json. Do not assume packaging output is incremental or cache-backed.
- Native dependencies such as
sharp, Electron, Vite, tsdown, and TypeScript are pinned/overridden in pnpm-workspace.yaml; change them deliberately. - Audio in wscrcpy is intentionally opt-in by default. When audio and control are both enabled,
createScrcpyOptions(packages/wscrcpy/src/options.ts) defaultsclipboardAutosynctofalsebecause clipboard device messages can destabilize the controller while streams keep running; an explicit user preference always wins. Do not gate audio playback on the host platform — WebCodecs + Web Audio work identically on Windows/macOS/Linux. - Wscrcpy defaults to forward tunnel mode (
tunnelForward: truein createScrcpyOptions). Reverse mode assigns video/audio/control by TCP accept order, but the adb server forwards the device's connections concurrently and may deliver them out of order on Windows, swapping the control and audio sockets (audio hangs forever, control writes are silently discarded). Forward mode identifies each stream by ADB protocol local-id, which removes the race. - The desktop app is mostly JavaScript/JSDoc, while workspace packages may be TypeScript. Do not add broad strict TS assumptions to the desktop renderer/main app.
- Use kebab-case for new directories and files.
- develop.md - developer setup, architecture, and contribution basics.
- README.md, README-CN.md, and README-RU.md - user-facing project overview.
- packages/electron-setup/README.md - Electron plugin/window framework.
- packages/electron-ipcx/README.md - function-friendly IPC contract.
- docs/en/ and docs/zhHans/ - VitePress product documentation.