Stealth screen sharing for macOS — share your screen in a second Google Meet without the first meeting knowing.
You're in Meet #1 sharing your screen. You need to also share your screen with someone in Meet #2 — without Meet #1 detecting anything.
┌──────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ Your Screen │────▶│ GhostScreen │────▶│ Chrome Tab │
│ │ │ (Electron app) │ │ localhost:9777 │
│ │ │ captures screen │ │ shows your │
│ │ │ via WebSocket │ │ screen live │
└──────────────┘ └─────────────────┘ └──────────────────┘
invisible to │
screen share ┌─────▼──────────┐
│ Meet #2 │
│ "Share Tab" │
│ this tab │
└────────────────┘
- GhostScreen runs as an invisible Electron app (content-protected, no focus steal)
- It captures your screen at 15 FPS and streams via WebSocket
- A local viewer page (
localhost:9777) displays the live stream - In Meet #2, you "Share a Tab" → select the viewer tab
- Meet #1 sees nothing different — GhostScreen is invisible to screen capture
cd ghost-screen
npm install
npm start- Start the app — it auto-starts streaming
- Press
⌘⇧Vor click "Open Viewer" to open the stream in Chrome - In Meet #2: click "Present" → "A Tab" → select the
localhost:9777tab - Done! Meet #1 is completely unaware
| Shortcut | Action |
|---|---|
⌘⇧S |
Start / Stop streaming |
⌘⇧V |
Open viewer in browser |
⌘⇧P |
Show / Hide control panel |
| Key | Action |
|---|---|
S |
Toggle FPS stats |
F |
Toggle fullscreen |
In the control panel you can adjust:
- FPS (1-30): Higher = smoother but more CPU. 15 is recommended.
- Quality (10-100%): JPEG quality. 70% is a good balance.
| Feature | How |
|---|---|
| Invisible to screen share | setContentProtection(true) — macOS excludes the window from capture |
| No focus steal | focusable: false + type: 'panel' — never takes focus from Meet |
| Hidden from dock | app.dock.hide() — no dock icon |
| Hidden from Cmd+Tab | skipTaskbar: true |
| All workspaces | setVisibleOnAllWorkspaces(true) |
- Main Process: Electron app that captures screen using
desktopCapturer, runs Express HTTP server + WebSocket server - Control Panel: Content-protected overlay window for managing the stream
- Viewer Page: Plain HTML page served at
localhost:9777that receives JPEG frames over WebSocket and displays them
On first run, grant these in System Settings → Privacy & Security:
- Screen Recording: Required for
desktopCapturer - Accessibility: May be needed for global shortcuts
| Issue | Fix |
|---|---|
| Black screen in viewer | Grant Screen Recording permission, restart app |
| Choppy stream | Lower FPS to 10, lower quality to 50% |
| Port in use | Another instance may be running. Kill it: lsof -i :9777 |
| High CPU | Lower FPS and quality in the control panel |