{"id":29117422,"url":"https://github.com/daniwasonline/swapper","last_synced_at":"2025-06-29T12:01:54.420Z","repository":{"id":301432136,"uuid":"1007499103","full_name":"daniwasonline/swapper","owner":"daniwasonline","description":"Swap between machines on a personal Proxmox virtualisation host with ease.","archived":false,"fork":false,"pushed_at":"2025-06-26T21:21:56.000Z","size":64,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-26T21:51:04.210Z","etag":null,"topics":["bun","gpu-passthrough","proxmox","proxmox-ve","usb-passthrough","virtual-machine","vm"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daniwasonline.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-24T05:14:12.000Z","updated_at":"2025-06-26T21:22:00.000Z","dependencies_parsed_at":"2025-06-26T21:51:11.563Z","dependency_job_id":"d3afc689-3548-4d10-ab03-e2038db47696","html_url":"https://github.com/daniwasonline/swapper","commit_stats":null,"previous_names":["daniwasonline/swapper"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/daniwasonline/swapper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniwasonline%2Fswapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniwasonline%2Fswapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniwasonline%2Fswapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniwasonline%2Fswapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daniwasonline","download_url":"https://codeload.github.com/daniwasonline/swapper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daniwasonline%2Fswapper/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262589813,"owners_count":23333250,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","gpu-passthrough","proxmox","proxmox-ve","usb-passthrough","virtual-machine","vm"],"created_at":"2025-06-29T12:00:54.758Z","updated_at":"2025-06-29T12:01:54.411Z","avatar_url":"https://github.com/daniwasonline.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Swapper\n\nA REST API for easily swapping between virtual machines on a personal Proxmox virtualisation host. Useful for certain niche cases, i.e. single-GPU IOMMU, where you have a single GPU and want to swap peripherals between virtual machines.\n\n## Roadmap\n- [x] REST API to swap between virtual machines\n  - [x] Fast caching for burst requests\n  - [x] Basic bearer authentication\n  - [ ] More advanced security \u0026 authentication\n  - [ ] Support for access with scoped Proxmox VE token/users\n  - [ ] Configurable rate limiting\n- [ ] API frontend applications\n  - [ ] Web UI (probably written in React?)\n  - [ ] Command-line tooling\n  - [ ] Apple shortcut (😭)\n- [x] Automatically detect swappable machines with a tag\n- [x] Easy to use JSON5 configuration (in VM notes)\n- [ ] Device management\n  - [x] USB device support\n  - [ ] PCI(e) device support (\\* API prepared but not implemented at this point)\n  - [x] Hot-plug (automatically remove/add device to active VM as it's plugged in/out)\n  -  NOTE: This only works with mapped devices at the moment!\n  - [x] Dynamic loading on startup (only load devices connected to host on startup)\n\n## Usage\nTo use Swapper, you'll need:\n- Bun.js (https://bun.sh/)\n- Proxmox VE 8.0+ (https://pve.proxmox.com/)\n- Valkey (https://valkey.io/) 7.0+ or compatible equivalent with Redis 2.6+\n  - **No persistence is required**: KV is ephemeral and is only used for queue/messaging, caching, and state.\n\n### Manual installation\n- Clone this repository\n- Install dependencies with `bun install`\n- Copy `.example.env` to `.env.local` and fill in details\n- Run with `bun run src/index.ts`\n- Access the API at `http://127.0.0.1:8555/`\n\n### Docker installation\n- **Compose**: Refer to `example.docker-compose.yml`.\n- **`docker run`**: No instructions at this time (coming whenever, submit a PR!)\n\n### Configuration\nSwappable QMs are automatically detected based on tags. Assign a QEMU machine with the tag `swapper` to mark it as swappable.\n\nConfigurations are managed with a [JSON5](https://json5.org/) snippet, located in the notes of a swappable QM. The configuration is parsed with special markers. See the [examples folder](examples) to see how this works.\n\n## Questions \u0026 Troubleshooting\n### Why is Swapper consistently hitting my Proxmox instance?\nSwapper continuously polls your Proxmox instance for changes in host configuration, as well as to update the cache. Some of these intensive features (i.e. the event handler) cannot be disabled at the moment; I may add configuration options to disable them in the future.\n\nIn the mean time, you should probably disable any rate limiting for the API on your Proxmox instance or intermediate proxies.\n### I can't use PCI(e) devices in the Swapper configuration!\nIn its' current state, Swapper only manages USB devices. I'll probably add support for PCI devices in the future, but I personally haven't had the need for swapper to manage PCI devices just yet.\n### What authentication methods are supported?\nAt the moment, Swapper only uses Bearer authentication. When this isn't configured, the API is only accessible from localhost.\n### I found a bug/have a feature request/whatever!\nPlease open an issue or pull request.\n\n## Personal motivation\n*This is a long-winded one, bear with me.*\n\nI've dreamed of having a hypervisor setup on my PC for a *very long time* (since 2020), mostly because I wanted to have fast access to multiple OSes--essentially a fancier version of dual-boot. When I first thought of the idea, I didn't have sufficient resources (RAM, storage, nor CPU) to run anything like this; however, time's passed, and I now have a very capable machine with very capable hardware.\n\nI switched from Windows 11 to a Proxmox-based setup in 2025. However, I ran into three huge issues:\n- I couldn't easily switch between VMs: I had to manually stop the running VM with Proxmox before starting another one\n- I swap my USB accessories between my MacBook and my PC, and Proxmox made it a huge pain in the ass to boot a VM without everything plugged in (please add the ability to boot a VM without a configured USB device plugged in, Proxmox!!!)\n\nFor this reason, I wrote Swapper 1.0: a Bash script that would stop a runnable VM, remove my keyboard, mouse, and microphone from it (in case I wanted to start the VM without the devices), then start another VM. This worked fine, mostly getting me through the remainder of the academic year. Fast-forward to now (June 2025), and I now have far more free time on my hands.\n\nAs said before, Swapper 1.0 worked fine, but it was *sloooow*. The script took about 10 seconds to place the initial swap request, and my primary means of accessing Swapper (an Apple Shortcut with SSH) made that far slower than I wanted it to be. I also wanted to have hot-plug and dynamic device sync (i.e. remove USB device =\u003e automatically remove from the VM), so I decided to rewrite Swapper 2.0 as a REST API--in spaghetti TypeScript, with Hono, on Bun, mostly because I cba to write a more elegant solution in Rust or Go or whatever.\n\nCould it be better? Yep. Is it better than Swapper 1.0? Absolutely.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniwasonline%2Fswapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaniwasonline%2Fswapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniwasonline%2Fswapper/lists"}