ADB Master — a web interface for managing Android devices via ADB. Monorepo with npm workspaces: server/ (Express + TypeScript), client/ (React + Vite + TypeScript), and relay/ (WebSocket tunnel for remote access).
npm install # Install all dependencies (root + workspaces)
npm run dev # Start server (:3000) + client (:5173) concurrently
npm run dev:server # Server only (tsx watch)
npm run dev:client # Client only (vite)
npm run dev:relay # Relay server only (tsx watch, :8080)
npm run build # Build server + client for production
npm run build:relay # Build relay for production
# Type checking
npx -w server tsc --noEmit
npx -w client tsc --noEmit
npx -w relay tsc --noEmit
# Client production build
npx -w client vite build
# Relay mode (server connects to remote relay)
RELAY_URL=https://your-vps.com RELAY_PASSWORD=optional npm run dev:server-
Server (
server/src/): Express REST API + Socket.IO (4 namespaces:/devices,/logcat,/shell,/screen)services/adb.service.tsis the single gateway to theadbbinary — all other services go through it- Uses
execFile(neverexec) for security - Zod validators in
validators/are applied viamiddleware/validate.ts middleware/device-guard.tschecks device serial exists before route handlersmiddleware/sanitize.tsblocks dangerous shell commands- Services:
adb,device,device-info,app,file,screen,intent,input,port,settings,shell - Screen streaming uses
sharpfor PNG→JPEG conversion (5-15x smaller frames); binary Socket.IO transport /screennamespace also handles low-latency input events (input:tap,input:swipe,input:keyevent,input:text)relay/relay-client.ts— connects to relay server for remote access mode; exposes session info viaGET /api/relay/status
-
Client (
client/src/): React 19 + React Router 7 + Zustand state- Pages: Devices, Device Info, Apps, Files, Network, Logcat, Terminal, Input, Screen, Settings
- API layer in
api/uses Axios with dynamic baseURL (local/apior remote relay) - Socket.IO client in
socket/socket-client.ts— 4 connections, supports local + remote mode - Screen page: receives binary JPEG frames, decodes off-thread via
createImageBitmap, sends input via socket - Theming via CSS custom properties in
theme/global.css(data-themeattribute) - i18n via i18next — translations in
i18n/en.jsonandi18n/ru.json store/connection.store.ts— local/remote connection mode with localStorage persistence- Header shows relay session badge when server is connected to a relay; Connection Modal shows share URL with copy button
-
Relay (
relay/src/): WebSocket tunnel server for remote access- Session management with UUID tokens
- HTTP request tunneling over WebSocket (JSON + base64 bodies)
- Agent (server) authenticates with secret, clients authenticate with session ID + optional password
- Auto-cleanup of expired sessions
- TypeScript strict mode everywhere
- Express route params require
as stringcast (Express 5 types returnstring | string[]) - Server types in
server/src/types/, mirrored inclient/src/types/ - API contract defined in
openapi.yamlat project root - CSS files co-located with components (e.g.,
Button.tsx+Button.css) - CSS uses
var(--color-*)tokens — never hardcode colors - Font:
var(--font-mono)for data/code,var(--font-sans)for UI text - All user-facing strings go through i18next
t()function - Shell inputs are sanitized to prevent injection (reject
;|$(){}` etc.)
server/src/services/adb.service.ts— ADB execution gateway (security boundary)server/src/utils/command-whitelist.ts— blocked command patternsserver/src/utils/adb-parser.ts— parseadb devicesand logcat outputserver/src/relay/relay-client.ts— relay tunnel client for remote access + session info APIserver/src/routes/relay.router.ts— relay status endpoint (GET /api/relay/status)server/src/socket/screen.socket.ts— screen streaming (JPEG frames) + socket-based inputclient/src/App.tsx— routing configurationclient/src/components/layout/AppShell.tsx— main layout + device socket listenerclient/src/store/device.store.ts— selected device stateclient/src/store/connection.store.ts— local/remote connection staterelay/src/relay-server.ts— relay server with session + tunnel logicopenapi.yaml— full API contract