main
StreamDeck – Custom Touchscreen Stream Deck
A native macOS Stream Deck replacement for HDMI touchscreens. Built with Electron, it stays on a dedicated secondary monitor and sends keystrokes/clipboard/shell commands to whatever app you're working in — without stealing focus.
Features
- Full grid of programmable buttons – 6×3 configurable per page
- Multiple pages – swipe or tap arrows/dots to navigate
- Realtime system monitor page – CPU usage (overall + per-core), memory usage, uptime, load
- Native macOS actions:
keystroke– sends keyboard shortcuts to your currently active app (e.g.cmd+v,ctrl+up,space)copy/paste/cut– clipboard operations via NSPasteboardshell– runs shell commandsosascript– runs AppleScriptapp– opens any macOS applicationurl– opens URLs in default browsersleep– puts Mac to sleep
- Touchscreen-optimized – large touch targets, frameless window, auto-fullscreen
- No focus stealing – app hides itself before sending keystrokes, so clipboard and shortcuts go to your previous app, not the StreamDeck
Requirements
- macOS (tested on Sequoia 15.x)
- Node.js 18+ (for development /
npm install) - Touchscreen with USB touch controller (e.g. WCH
USB2IIC_CTP_CONTROL) - Touch-Base / UPDD touch driver – required separately! The touchscreen will not work without this driver on macOS. Download and install from touch-base.com. After installation, use the UPDD Commander to map the touch device to your secondary monitor.
Quick Start
# 1. Install dependencies
cd streamdeck
npm install
# 2. Copy config template and customize
cp config.template.json config.json
# Edit config.json to set up your buttons
# 3. Run!
./start.sh # Electron app (touchscreen)
# or
./start.sh server # Web-based mode for testing in browser
For the Electron app:
- The window opens automatically on your second monitor (touchscreen)
- Fullscreen is enabled automatically on start
- Press F11 to toggle fullscreen
- Press F2 to show the debug event overlay
Button Configuration
Edit config.json. Each button can have:
{
"label": "Button Name",
"icon": "🔔",
"color": "blue",
"actions": [
{ "type": "keystroke", "value": "cmd+v" },
{ "type": "shell", "value": "open -a Safari" }
]
}
Available action types
| Type | Value | Effect |
|---|---|---|
keystroke |
cmd+v, ctrl+shift+z, space, f2 |
Sends keyboard shortcut to active app |
shell |
open -a Safari |
Runs shell command in background |
osascript |
set volume 50 |
Runs AppleScript |
app |
Visual Studio Code |
Opens application |
url |
https://github.com |
Opens URL in browser |
copy |
none | Copies selected text (Cmd+C) |
paste |
optional text |
Pastes text (Cmd+V) |
cut |
none | Cuts selected text (Cmd+X) |
sleep |
none | Puts Mac to sleep |
Key syntax
- Modifiers:
cmd,ctrl,alt,shift - Special keys:
up,down,left,right,space,return,tab,escape,f1–f12 - Combine with
+(e.g.cmd+shift+z,ctrl+up) - Regular characters are typed literally (e.g.
a,1,Hello)
Project Structure
streamdeck/
├── config.json # Your button configuration (local, not in git)
├── config.template.json # Template for config
├── electron-main.js # Electron main process (window, IPC, actions)
├── preload.js # Context bridge (renderer ↔ main)
├── server.js # Node.js web server for browser mode
├── package.json
├── start.sh # Convenience launcher
├── public/
│ ├── index.html
│ ├── app.js # Frontend logic
│ └── style.css # Touch-optimized UI
└── README.md
License
MIT
Description
Languages
JavaScript
81%
CSS
14.8%
HTML
2.7%
Shell
1.5%
