Open-source project
tiny-pilot/tinypilot avatar
tiny-pilot/tinypilot

TinyPilot: the installer pipes the master branch into bash, then reboots the Pi

Use your Raspberry Pi as a browser-based KVM.

3,478 stars292 forksPythonMIT

At a glance

What is it?
TinyPilot turns a Raspberry Pi into a browser-based KVM for video, keyboard and mouse. Its one-command install fetches a script from an unpinned branch, its diagnostics live in a privileged path outside the app, and its authentication shows up only in the dependency list.
Who is it for?
Adequate fit: someone with a spare Raspberry Pi 4B and a target machine that needs occasional hands-on control from another screen, on a network where reaching the Pi by hostname is acceptable. It fits badly for a target machine that must not be reachable, or where the person holding the keyboard is not the person trusted with the network.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 49 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The install command pipes the master branch into bash and reboots the device

The requirements section is one line: a Raspberry Pi 4B running Raspberry Pi OS Trixie, 64-bit. Given that, the page promises installation in two commands, and both are in one shell block:

bash
curl \
  --silent \
  --show-error \
  https://raw.githubusercontent.com/tiny-pilot/tinypilot/master/get-tinypilot.sh | \
    bash - && \
  sudo reboot

What that block does is fetch `get-tinypilot.sh` from a raw URL that names the `master` branch and nothing else, hand it to bash, and reboot. There is no tag, no commit and no hash in the URL, and no step at which the script's contents are shown or confirmed. The file being run is committed at the root of the repository, so what executes is whatever that branch holds at the moment of the request rather than a released version. The reboot in the same block is the second command. For anything past this point the page links out: developer installation is in CONTRIBUTING, and advanced options are a wiki page.

After the reboot the dashboard answers at a bare hostname

The next thing the page tells you is that when the device comes back you reach TinyPilot by visiting the Pi's hostname in a browser, with `raspberrypi` given as the example. So the default answer is a hostname on the local network and nothing else: no port, no scheme upgrade, no certificate, and no step in which a password is created or a credential is supplied. That is the whole of what the page says about reaching the interface, and it is the interface through which video, keyboard and mouse pass.

The five capabilities the feature list names are video capture over HDMI, DVI or VGA, keyboard forwarding, mouse forwarding, fullscreen mode, and pasting text from the clipboard. One caveat attaches to the hardware rather than the software. If you are using an HDMI to CSI capture chip, as a Voyager series device does, the page sends you to a separate wiki page for the additional configuration steps video capture needs, which means the capture path is not identical between a USB dongle and a CSI chip.

The browser route is also the only route documented for the software itself. Everything else on the page is about the hardware you can buy or assemble.

Diagnostics run as root from a path outside the application

Troubleshooting splits in two. If the dashboard loads, you click Logs at the bottom of the main dashboard, and the page spells that button out in a sentence that also contains the typo retrive. If the dashboard does not load, you SSH into the device and run one command:

bash
sudo /opt/tinypilot-privileged/scripts/collect-debug-logs

That path is the useful fact. The application is not the only thing installed on the device: there is a privileged tree at `/opt/tinypilot-privileged/` holding its own scripts, outside the application and outside whatever the dashboard can reach. Diagnostics therefore need root, and the page routes you to it rather than around it. The result is what you would attach to a bug report, and the page links both the issue template and a wiki page on troubleshooting.

The repository layout matches the split. `bundler/`, `scripts/`, `dev-scripts/`, `debian-pkg/` and a `quick-install` entry sit beside `app/`, which is the pattern of a project that ships a package, a bundle and a set of install helpers rather than a single script.

The video and desktop layers are other people's projects

The acknowledgments section names what the KVM is actually assembled from. uStreamer is listed first, then Flask with Flask-SocketIO, then vdesktop, litestream, Raspberry Pi, and nginx. That is the architecture in one paragraph: video capture from uStreamer, a virtual desktop from vdesktop, a Flask application talking over Socket.IO, nginx in front, and litestream for storage.

The Python side confirms it and pins it hard. `requirements.txt` carries eight direct dependencies, all with exact versions: eventlet, Flask, Flask-SocketIO, Flask-WTF, python-dotenv, passlib and PyYAML. Under a heading for indirect dependencies it lists eighteen more, from bidict and blinker through Werkzeug, WTForms, Jinja2, python-socketio, python-engineio and wsproto. Every entry uses an equality pin, and a comment at the top of the file points at a section of CONTRIBUTING for how to update them. So the dependency graph is small, fully pinned and described in one file.

An `ARCHITECTURE.md` sits at the root of the tree, and the front page never links it.

Authentication appears in the dependency list and nowhere in the prose

Two of those eight direct dependencies have a bearing on access. Flask-WTF is a form integration, passlib is a password hashing library, and python-dotenv loads settings from an environment file. Together they are what a dashboard with a login form is built from. The feature list says nothing about accounts, and neither does the installation section, the diagnostics section or the acknowledgment list. The one thing the page says about reaching the interface is that you visit the Pi's hostname in a browser.

That gap is worth naming precisely, because it is not the same as saying there is no access control. A `requirements.txt` is a declaration of intent, not a description of behaviour, and this repository also carries a `bundler/` directory, a Debian packaging directory and a `quick-install` entry, none of which the page explains. So what can be said from here is narrow: the prose never says how the dashboard is protected, and the dependencies imply a form and a password hash exist somewhere behind it. Anyone putting a Pi on a shared network should read the wiki on installation options before deciding that a bare hostname is enough.

Keyboard and mouse are opened by device paths named in an environment example

The clearest statement of the input mechanism is not in the feature list but in the environment example file at the root. It defines three variables. `GATEKEEPER_BASE_URL` is described as optional, for development, to be replaced with the base URL of a local Gatekeeper dev server, and it is said to default to Gatekeeper's production URL when it is not set, with the example value pointing at localhost port 2001. `KEYBOARD_PATH` and `MOUSE_ABSOLUTE_PATH` are described for development as set to `/dev/null` so errors do not appear when the environment cannot reach the real `/dev/hid` devices.

So input is not abstracted behind an API in this layer. The keyboard and the absolute pointing device are each named as a filesystem path, and the example works by pointing them at nothing. The same file also names a second service, Gatekeeper, with its own development server and its own production default, which is why a device can be pointed at a local backend during development and at the hosted one otherwise without a rebuild.

The comment above the input variables misspells development as developmenet, which is a small sign of how lightly that file gets read.

Three Python linters, two test runners, and no JavaScript runtime

A Python project with a package manifest is worth a look. This one has no runtime dependencies at all: `package.json` carries a `type` of module and a `devDependencies` block with eight entries, all tooling. `@eslint/js`, `eslint`, `eslint-plugin-html` and `globals` are the linting side, `prettier` the formatting side, and the test side has both `@playwright/test` and `playwright` at 1.60.0 plus `mocha` at 11.7.6. Two test runners for a codebase whose server is Python is a choice worth noticing, and `playwright.config.js` and an `e2e/` directory at the root are the browser half of it.

The Python tooling is broader still, and overlapping. `.pylintrc`, `.ruff.toml`, `.style.yapf` and `.yapfignore` mean two linters and a formatter configured at once, `.shellcheckrc` covers shell, `.lintianignore` covers the Debian package checks, and `.dockerignore` and `.prettierignore` do what their names say. A `tinypilot.code-workspace` file commits an editor layout, and an `__init__.py` sits at the repository root, which makes the checkout itself importable as a package.

Five features are documented for everyone, the rest sit behind a paid tier

The page is honest about this split, which is unusual in a readme. The five free capabilities are video capture, keyboard forwarding, mouse forwarding, fullscreen mode, and pasting text from the clipboard. Then a section headed Upgrade to Pro lists what a professional user adds: booting into a virtual disk drive, loading a virtual disk drive from a URL, controlling TinyPilot programmatically, mounting virtual media in CD-ROM mode, and Wake on LAN. Every one of those five is documented by a link to a blog post or a product page, not by anything in this repository.

The hardware section is the same split in physical form. The Voyager 3 is described as the latest professional-grade device, rack-mountable with active cooling, a status screen, an HDMI loop output for passthrough to a local monitor, 1920x1200 video capture, Power over Ethernet on a variant, an optional second Ethernet interface, FCC and CE compliance, and TinyPilot Pro software included with lifetime updates under a 12-month extendable warranty.

Against that, the build-your-own list is four required parts and two optional ones, and the capture dongle is the part with a caveat: no brand name, several variants, all built on the same MacroSilicon 2109 chip, available for ten to fifteen dollars on two marketplaces.

Editorial conclusion

Adequate fit: someone with a spare Raspberry Pi 4B and a target machine that needs occasional hands-on control from another screen, on a network where reaching the Pi by hostname is acceptable. It fits badly for a target machine that must not be reachable, or where the person holding the keyboard is not the person trusted with the network. Four things are worth settling first. The install command pipes a script fetched from the master branch into bash and then reboots the device, so there is no tag or hash in the URL and no confirmation step. The dashboard is reached at a bare hostname with nothing on the page about transport or access control, and the packages that imply authentication are only visible in the dependency list. Diagnostics require root through a separate privileged path. And the five features the page documents are the free ones; virtual disk boot, loading media from a URL, programmatic control, CD-ROM virtual media and Wake on LAN are all listed under a paid tier whose documentation lives outside this repository. Nothing above was installed or run.

Frequently asked questions

What is a TinyPilot?

Software that turns a Raspberry Pi into a browser-based KVM: video capture over HDMI, DVI or VGA, keyboard forwarding, mouse forwarding, fullscreen mode, and pasting text from the clipboard. You reach it from a browser at the Pi's hostname.

How do you install TinyPilot?

On a Raspberry Pi 4B running Raspberry Pi OS Trixie, 64-bit. One command fetches a script from a raw URL on the master branch, pipes it to bash, and reboots the device. After the reboot you open the Pi's hostname in a browser. Developer and advanced options are separate links.

What is TinyPilot used for?

Controlling another computer's screen, keyboard and mouse from a browser on a different machine. The page also describes assembling the hardware yourself from a Raspberry Pi 4B, an HDMI to USB capture dongle on the same MacroSilicon 2109 chip, a 3 Amp power supply, cables and a Class 10 microSD card.

How much does the TinyPilot KVM cost?

The page carries no price for the official device and points at a shop page for it. For a self-built one it lists a Raspberry Pi 4B, an HDMI to USB dongle it says is available for ten to fifteen dollars on two marketplaces, a 3 Amp power supply, cables and a microSD card, and links a third-party tutorial titled TinyPilot: Build a KVM Over IP for Under $100.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. tiny-pilot/tinypilot on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tiny-pilot-tinypilot.svg)](https://hysenlabs.com/projects/tiny-pilot-tinypilot)