# WebDeck: hosting your own Stream Deck alternative on the machine you control

> WebDeck is a Flask application that turns any browser on a touchscreen into a configurable control panel for the computer hosting it, shipped as a portable Windows executable and licensed under GPL-3.0.

**Lenochxd/WebDeck** — The free stream deck alternative

- Repository: https://github.com/Lenochxd/WebDeck
- Website: https://webdeck.app
- Stars: 958 · Forks: 62
- Language: Jinja
- License: GPL-3.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/lenochxd-webdeck

## WebDeck turns a browser tab into a Stream Deck style control panel

The project description is one line: the free Stream Deck alternative. The mechanism behind that claim is a Flask application that the user hosts on their own computer, and the interface that the user drives is a web page opened in a browser on any device with a touchscreen.

The contrast the README draws is with Elgato hardware. A physical Stream Deck needs dedicated equipment. WebDeck replaces the hardware with a server you run yourself and a URL you open on a phone or tablet. The buttons on the page are the controls, and they are arranged in a grid whose size the project lets you change, an algorithm credited in the contributor table to one of the maintainers.

That framing matters for who this is for. The intended user is a person who wants to trigger actions on their own machine from a device that already has a screen, typically a streamer or a person giving a demo who does not want to buy a dedicated panel. The application ships as a portable zip, so it also suits anyone who wants a remote control surface without installing system-wide software.

The tradeoff is immediate. You are running a local web server that injects input into your desktop, and the project states plainly that it currently supports Windows.

## Flask and Socket.IO carry the button presses between the browser and the host

The dependency list in requirements.txt shows how the pieces fit together. The web layer is flask, and the live channel between the browser and the host is flask_socketio with simple-websocket underneath it, which is how a button press on a phone reaches the Python process running on the desktop and how state such as a now playing track gets pushed back.

The presentation layer is Jinja, which is why the repository lists templates/ and static/ at the top level and lists Jinja as the primary language of the project. The Flask application in app/ renders the pages, and the tray program in console.py and the entry point in run.py sit beside the webdeck/ package that holds the version metadata read during packaging.

Around that core the requirements list is a catalogue of operating system integrations. mss handles screen capture, pyautogui and keyboard handle input injection, pycaw and pyaudio deal with audio, pyperclip covers the clipboard, and pywin32 exposes Windows APIs. The media and streaming entries show the intended use: spotipy for Spotify, python-vlc and nava and pydub for media playback, obs-websocket-py for controlling OBS, and pywebview for embedding a web view in a desktop window. customtkinter and easygui and pystray cover the desktop and system tray pieces that make the application feel like a local program rather than a bare server.

## Getting it running means unzipping a portable build and starting the executable

The installation instructions in the README are short, and they assume you are on Windows. You download the latest version from the Releases section on GitHub, extract the archive, and start the program.

```bash
WebDeck.exe
```

The archive named in the instructions is WebDeck-win-amd64-portable.zip, and the word portable is the point: nothing is installed system-wide and there is no separate setup on the phone or tablet. To connect a device, you click the tray icon and scan the QR code that appears, which is why the requirements include the qrcode package.

If you would rather run from source, the repository root holds run.py, console.py, and setup.py, and the third-party dependencies are pinned in one file:

```python
flask
flask_socketio
keyboard==0.13.5
pyautogui==0.9.53
```

Those pins are worth pausing on. keyboard is held at 0.13.5 and pyautogui at 0.9.53, and webcolors and customtkinter are pinned as well. Pinned versions give reproducible behaviour on a machine you control, and they also mean a fresh environment can fail to build when a pinned release is pulled from a package index.

## cx_Freeze packages the Flask app into a self-contained Windows binary

setup.py explains how the portable zip is produced, and it is not a plain pyinstaller invocation. The file imports cx_Freeze, which is the freezer that turns the Python application into a standalone executable that carries its own interpreter.

The script reads the version before doing anything else:

```python
with open("webdeck/version.json", encoding="utf-8") as f:
    version_info = json.load(f)
    version = version_info["versions"][0]["version"]
```

So the release number displayed by the application comes from a JSON file inside the webdeck package, and the packaging step reads the same source of truth. The file then builds an exclusion list, combining a hardcoded set with the patterns parsed out of .gitignore, and it uses the pathspec library to match files against those patterns, including negated patterns for anything the ignore rules want to keep. The build script also raises the recursion limit, sets the start time, and imports modules for downloading and zipping, which points to additional release steps beyond freezing.

This build shape is why the project can promise a portable archive. It is also why the application is Windows shaped throughout, since pywin32 and pycaw and the general approach all assume that platform.

## Windows only, and the project says Wine will not close the gap

Platform support is the sharpest boundary in this project. The README states that WebDeck currently supports Windows, that versions for Linux and macOS are planned, and, unusually, that Wine emulation is not a viable solution for Linux compatibility.

That last sentence rules out the usual escape hatch. When a Windows application can be run through a compatibility layer, you can often treat the platform gap as closed. Here the authors have checked and say otherwise, which suggests the application depends on Windows input and display facilities that a translation layer does not reproduce faithfully.

There is also a compatibility question on the browser side. The project keeps a public test table listing results across devices and browsers, and you can contribute results through a web page linked from the README. The existence of that table is a hint about the shape of the problem: a touchscreen interface driven by browser events behaves differently depending on how the browser reports touch input and how the page is scaled.

For a team standardising on macOS or Linux desktops, this project is not currently a candidate, and the project itself says so rather than leaving it ambiguous.

## Where WebDeck is the wrong tool

Several scenarios do not fit this project, and the documentation gives enough to name them.

The first is a need for input that only a physical deck provides. A hardware Stream Deck requires physical equipment of its own. WebDeck is a server and a page. If the Flask process is not running, there is no panel.

The second is a requirement to operate on machines you do not own. WebDeck runs on the host machine and injects input into that machine's session, so it does not give you remote access to somebody else's computer. It is a control surface for your own desk.

The third is the silence in the documentation about exposure. The README does not document how the local server is bound or whether a passphrase protects the pages, and the FAQ lives in a separate document at docs/FAQ-en.md rather than in the README itself. Given that the server can inject keystrokes into the host session, whether it is reachable beyond your own network is the first thing to check in your own deployment rather than assume.

## GPL-3.0, a last push on 2026-05-03, and releases that stopped in 2024

WebDeck is distributed under the GPL-3.0 licence, with the licence text in the LICENSE file at the repository root. That matters more here than for a typical library because the application is a program you run, and anyone who distributes a modified copy has obligations under the same licence. It is not a problem for personal use, and it is worth reading the licence terms if you plan to bundle it in a product.

On activity, the last push to the repository was on 2026-05-03. The most recent tagged release, however, is WebDeck v1.8.7 from 2024-09-26, preceded by v1.8.6 in August 2024 and v1.8.5 in April 2024. The gap between the last push and the last release tells you something the push date alone does not: work has continued on the branch without producing new tagged builds, so the binary you download from the Releases page may be considerably older than the current source.

The repository also keeps French and Korean versions of the README, a Discord server and a Twitter account for support, and a GitHub issue tracker, and it accepts contributions by pull request. The FAQ in the README asks you to check docs/FAQ-en.md before asking questions, which is where device and browser compatibility detail lives.

## Conclusion

Adopt WebDeck if you want a Stream Deck style control surface, a custom grid of macros and media actions, and the freedom to host the server on the machine you already own, and if that machine runs Windows. Do not adopt it if you need Linux or macOS support, if you need a hardware device that works without a running PC, or if a copyleft licence is a problem for your distribution plans. Verify three things before you rely on it: that the pinned dependency versions still install on your Python, that the Flask server is not reachable from an untrusted network, and that the actions you automate work with your own input devices.

## FAQ

### How do I install and start WebDeck on my computer?

Download the latest version from the Releases section on GitHub, extract the contents of WebDeck-win-amd64-portable.zip to a folder of your choice, and run WebDeck.exe. On the mobile side there is nothing to install, you scan the QR code shown after clicking the tray icon.

### Does WebDeck work on Linux or macOS?

Not currently. The README states that WebDeck supports Windows, that Linux and macOS versions are planned, and that Wine emulation is not a viable solution for Linux compatibility.

### What is the difference between WebDeck and an Elgato Stream Deck?

The README describes the Stream Deck as hardware that requires physical equipment, while WebDeck is a Flask application hosted on your own computer and controlled from a browser on any touchscreen device. The buttons live in a grid served as a web page rather than on a dedicated panel.

### Which Python dependencies does WebDeck need?

requirements.txt lists flask, flask_socketio, keyboard==0.13.5, pyautogui==0.9.53, customtkinter==5.2.2, pywin32, mss, qrcode and many others. Several versions are pinned, including keyboard, pyautogui, webcolors and customtkinter.

### What licence is WebDeck released under?

WebDeck is released under the GPL-3.0 licence, with the licence text in the LICENSE file in the repository root.

## Sources

- [Lenochxd/WebDeck on GitHub](https://github.com/Lenochxd/WebDeck)
- [License: GPL-3.0](https://github.com/Lenochxd/WebDeck/blob/master/LICENSE)
- [Project website](https://webdeck.app)
- [README](https://github.com/Lenochxd/WebDeck/blob/master/README.md)
- [Releases](https://github.com/Lenochxd/WebDeck/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lenochxd-webdeck
