Understanding the escrcpy Monorepo Structure: A Deep Dive into the pnpm + Turborepo Architecture

escrcpy is organized as a pnpm + Turborepo monorepo that separates the Electron UI, reusable workspace packages, and documentation into distinct directories orchestrated by turbo.json.

The escrcpy repository (viarotel-org/escrcpy) serves as a modern Android screen mirroring application built on Electron. Its monorepo structure enables independent development of the scrcpy protocol stack, device management utilities, and the main desktop interface while maintaining tight integration through shared workspace tooling.

Top-Level Directory Layout

The repository root contains three primary directories that define the architecture:

  • desktop/ – The Electron application housing both main-process logic and renderer windows.
  • packages/ – Reusable libraries including the scrcpy protocol implementation, IPC layers, and device control modules.
  • docs/ – VitePress-powered documentation supporting multiple languages.

Additional directories like scripts/ and configs/ contain build and CI utilities, while pnpm-workspace.yaml defines the workspace boundaries.

The Desktop Application Layer

The desktop/ directory contains the complete Electron application, split between the main Node.js process and renderer windows built with Vite.

Main Process Entry Point

The application's lifecycle begins at desktop/electron/main.js. This file bootstraps the Electron environment using the plugin-based architecture provided by @escrcpy/electron-setup.

According to the source code, the main process loads plugins from @escrcpy/electron-setup and initializes the application window manager. This modular approach allows features to be registered dynamically rather than hard-coding them in the main entry file.

Renderer Windows Configuration

Unlike standard Electron apps with a single window, escrcpy manages multiple distinct renderer contexts. The desktop/vite.config.js defines separate Vite build entries for each window type:

  • main – Primary interface
  • control – Device control panel
  • explorer – File management
  • copilot – AI assistance features
  • terminal – Shell access
  • automation – Scripting interface
  • mirror – Screen mirroring view

Each entry point compiles independently while sharing common dependencies through the workspace configuration.

Workspace Packages Architecture

The packages/ directory contains six core libraries that implement the business logic independently from the Electron shell.

Core Electron Infrastructure

electron-setup/ provides the foundational plugin and window management primitives. The core API resides in packages/electron-setup/main/index.ts, exposing a window API for registering main-process modules. This abstraction layer allows the desktop application to instantiate and manage windows without directly coupling to Electron APIs.

electron-ipcx/ implements a function-friendly IPC contract between the main and renderer processes. It exposes ipcxRenderer and ipcxMain utilities used by the preload layer, replacing raw ipcMain/ipcRenderer calls with type-safe function invocations.

Scrcpy Protocol Implementation

wscrcpy/ is a self-contained Vue + TypeScript module that implements the complete scrcpy protocol stack. It exports two distinct APIs:

  1. Renderer-facing API – Wscrcpy component and composables for the UI layer.
  2. Main-process API – ByteBridge factory accessible via @escrcpy/wscrcpy/main.

This separation allows the protocol logic to remain agnostic of the Electron context while providing optimized entry points for each process type.

Device Control & Utilities

madb/ implements an MCP (Model Context Protocol) server for AI-agent Android device control via ADB/Yadb interfaces.

adbx/ serves as an injected adbkit layer that prefers yadb when available on the host device, providing enhanced performance over standard ADB connections.

shared/ contains platform-neutral utilities for device handling, networking, and mathematical operations used across all packages. The export hub resides at packages/shared/src/index.ts.

Build System and Task Orchestration

The monorepo leverages Turborepo (configured in turbo.json) to orchestrate builds and development commands across packages, while pnpm resolves workspace dependencies through pnpm-workspace.yaml.

Common development workflows include:


# Install all workspace dependencies

corepack enable pnpm && pnpm install

# Start the development environment (Turbo launches the Electron Vite server on port 1535)

pnpm dev

# Run type-check only for the wscrcpy package

pnpm --filter @escrcpy/wscrcpy typecheck

# Build the whole app for the current platform

pnpm build

# Sync i18n keys after editing locale JSON files

pnpm lang-sync

The --filter flag allows targeted operations on specific workspace packages without building the entire tree, significantly improving iteration speed during development.

Key Entry Points and File References

File Description
desktop/electron/main.js Main-process entry point; loads plugins from @escrcpy/electron-setup.
desktop/vite.config.js Vite configuration defining multiple renderer windows.
packages/electron-setup/main/index.ts Core API for registering application modules and windows.
packages/electron-ipcx/README.md Documentation of the IPC contract between renderer and main processes.
packages/wscrcpy/ Vue/TS scrcpy protocol implementation with dual-process API.
packages/shared/src/index.ts Export hub for platform-neutral utilities.
docs/en/guide/started.md User-facing getting started guide.

Summary

  • escrcpy uses a pnpm + Turborepo architecture to separate concerns between the Electron shell and business logic.
  • The desktop/ directory contains the main process entry at desktop/electron/main.js and multi-window Vite configuration.
  • Six workspace packages in packages/ handle IPC, protocol implementation, and device control, with wscrcpy being the core scrcpy stack.
  • Turborepo orchestrates builds through turbo.json, while pnpm workspaces manage dependency linking.
  • Development commands like pnpm --filter @escrcpy/wscrcpy typecheck enable targeted package operations.

Frequently Asked Questions

What build tools does escrcpy use for its monorepo structure?

escrcpy uses pnpm for package management and Turborepo for task orchestration. The pnpm-workspace.yaml file defines the workspace boundaries (including desktop/ and packages/*), while turbo.json configures the build pipeline and task dependencies. This combination enables efficient caching and parallel execution across the Electron application and workspace libraries.

How does the desktop application handle multiple renderer windows?

The application defines multiple entry points in desktop/vite.config.js, specifying separate builds for windows like main, control, explorer, copilot, terminal, automation, and mirror. Each window operates as an independent Vite entry point while sharing common dependencies through the workspace configuration, allowing specialized UI contexts without code duplication.

What is the purpose of the wscrcpy package in the monorepo?

wscrcpy is a self-contained Vue + TypeScript module that implements the complete scrcpy protocol stack for Android screen mirroring. It provides a renderer-facing API with the Wscrcpy component and composables for the UI, plus a main-process ByteBridge factory accessible via @escrcpy/wscrcpy/main. This dual-export pattern keeps the protocol logic decoupled from Electron specifics while offering optimized APIs for each process type.

How do I run commands for a specific workspace package?

Use the pnpm --filter flag followed by the package name as defined in its package.json. For example, pnpm --filter @escrcpy/wscrcpy typecheck runs the type-checking script only for the wscrcpy package. This filtering capability allows developers to lint, test, or build individual packages without waiting for the entire monorepo to process, significantly improving development velocity.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →