An open-source game launcher written in Node.js (Electron, React, TypeScript), Python, and Rust.
🍴 This is a personal fork of hydralauncher/hydra
This repository is not the official Hydra project.
All source under
src/,python_rpc/, andnative/belongs to the upstream projecthydralauncher/hydra, authored upstream by Los Broxas and licensed under their MIT License.This fork only repackages the same code with a macOS Intel x86_64 build matrix, pinned
libtorrent2.0.13 /cx_Freeze7.2.3, and personal DevOps tweaks. No source undersrc/,python_rpc/, ornative/has been added, removed, or modified —package.jsonkeeps"author": "Los Broxas"and the upstream repository URL.For the official project — releases, support, bug reports, source of truth — go to github.com/hydralauncher/hydra.
This repository is a personal snapshot of the upstream hydralauncher/hydra project. Every document in this folder — including this README, the in-repo
.cursorrules, the API host migration note, the postinstall patches, and the build/run instructions — was drafted and (re)organized by an AI assistant. The running code itself comes from upstream Hydra; AI here is the author of the documentation and developer ergonomics, not the implementation.If something in this README looks off, blame the AI first.
- Add games that you own to your library
- Have a nice profile that shows what you are playing to your friends
- Save your game progress in the cloud with Hydra Cloud
- Unlock achievements (RetroAchievements supported)
- Navigate through a rich catalogue with a powerful suggestion algorithm
- Discover new games that you haven't played before
libtorrent and cx_Freeze are pinned in requirements.txt so the
nightly Python RPC build is deterministic. When you change either pin:
- Update
hydra/requirements.txt. - Run
make python-rpclocally to refreshhydra-python-rpc/(or letnightly-python-rpc.ymlproduce the artifact and copy it into your localhydra-python-rpc/). - Re-run
yarn build:{linux,mac,win}so the bundled sidecar inextraResourcesactually carries the new libtorrent. Building TypeScript alone will not pick up a Python pin change.
For the full release process (tag-driven workflow, optional
RELEASE_NOTES.md curated-notes override, opt-out recipe, and the
softprops merge caveat) see
CONTRIBUTING.md.
This fork will probably not be updated to new upstream versions.
This is not a tracking fork. The purpose is to have a working copy of Hydra
at a known set of versions, with a .env and patches that keep the API
endpoints reachable right now, not forever. Specifically:
- I will not merge new releases from upstream automatically.
- I will not backport security fixes from upstream.
- I will not open PRs against upstream from this fork.
- If an upstream dependency is yanked or breaks, I will pin or replace it locally rather than re-sync the whole tree.
- If the
.envhostnames stop resolving again (see below), the README will be patched, not the binary.
Use upstream hydralauncher/hydra for anything you actually care about
shipping. Use this fork only if you want to build the version pinned in this
repo.
Pinned versions in this fork (see package.json, requirements.txt,
native/hydra-native/Cargo.toml):
| Component | Version |
|---|---|
hydralauncher (app) |
4.0.4 |
| Electron | 40.9.3 |
| Node (engine) | yarn >= 1.19.1, packageManager yarn@1.22.22 |
| Python | 3.9+ |
libtorrent |
== 2.0.13 (fork pin — pre-built wheels, no source build) |
cx_Freeze |
== 7.2.3 (fork pin — supports Python 3.9–3.11 cleanly) |
hydra-native (Rust addon) |
0.1.0, edition 2021 |
You need all of these on PATH before running any build script:
- Node.js 20.x or newer LTS (only used at build time; the bundled Electron carries its own runtime).
- Yarn 1.22.x (Classic) —
npmwill not work; the repo'senginesfield is literallynpm: "please-use-yarn". Don't fight it. - A C/C++ toolchain for native module compilation:
- Windows: Visual Studio 2022 Build Tools (Desktop development with C++).
- macOS: Xcode Command Line Tools (
xcode-select --install). - Linux:
build-essential+python3headers.
-
Used for the Python RPC sidecar at
python_rpc/. It links againstlibtorrentand is frozen into a binary viacx_Freezefor distribution. -
Install deps inside a venv (the repo includes a
.venv/— reuse or recreate):python3 -m venv .venv source .venv/bin/activate # or .venv\Scripts\activate on Windows pip install -r requirements.txt # libtorrent + cx_Freeze == 7.2.3
-
On Windows,
libtorrentis provided bylibtorrent-rasterbarfromChristoph Gohlke's wheels or your distro of choice. cx_Freeze will bundlelibcrypto-1_1.dll/libssl-1_1.dllfrom your Python install.
- Required for the NAPI native addon at
native/hydra-native/. It is built automatically bypostinstall→yarn build:nativeand outputshydra-native.nodeplus a.dTypeScript binding. - Install via rustup. A specific toolchain version is not pinned — any recent stable toolchain works.
The packaging step copies these into the final installer:
| OS | File (in binaries/) |
|---|---|
| Windows | binaries/7z.exe, binaries/7z.dll |
| macOS | binaries/7zz |
| Linux | binaries/7zzs, binaries/umu/umu-run |
Don't replace them unless you know what you're doing — node-7z shells out
to these paths at runtime.
For the AppImage / snap / deb / rpm targets:
dpkg-deb,rpmbuild,fakeroot,snapcraftas appropriate.extraResourcesincludesbinaries/umu/umu-run— UMU is used to launch Windows games via Proton on Linux.
- macOS: Xcode CLT + a valid code-signing identity if you want
notarizeto work (currentlynotarize: falseinelectron-builder.yml, so unsigned builds are fine for personal use). - Linux: GTK 3 headers, libnss3, libxss, libasound2 — anything
Electron 40 expects. On Debian/Ubuntu:
apt install libnss3 libatk-bridge2.0-0 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 libgbm1 libxss1 libasound2 libgtk-3-0. - Windows: WebView2 runtime (pre-installed on Win10+; otherwise bundled by electron-builder).
Copy .env.example to .env and fill in any keys you need. Vite injects
these at build time; once a binary is packaged, changing .env after the
fact has no effect on existing installations — values are hard-coded.
At minimum you need a working MAIN_VITE_API_URL. Auth, checkout, and
WebSocket URLs are optional depending on which features you actually use.
All commands assume you're at the repo root and have yarn on PATH.
yarn installThis runs postinstall, which:
- Builds the Rust NAPI addon (
hydra-native/hydra-native.node). - Runs
electron-builder install-app-depsto rebuild native deps against Electron's ABI. - Runs
scripts/postinstall.cjs(other housekeeping).
The first install will take a few minutes — most of it is compiling
libtorrent / node-7z / sharp / canvas native bits.
yarn devUses electron-vite dev. Renderer (React) gets HMR; main and preload
restart on file change.
yarn dev:big-pictureRuns just the Big-Picture UI under Vite — useful for styling work.
yarn buildThat runs typecheck (Node + Web tsconfigs) then electron-vite build,
producing out/main, out/preload, out/renderer, out/big-picture.
yarn build:python-rpcFalls back from python3 to python automatically. Output lands in
python_rpc/build/.../hydra-python-rpc/.
yarn build:nativeWraps scripts/build-native-addon.cjs. Output: native/hydra-native.node
plus a .d.ts.
yarn build:win # NSIS installer + portable .exe
yarn build:mac # DMG (notarize: false)
yarn build:linux # AppImage + snap + deb + rpmEach of these runs build:native + build:python-rpc + electron-vite build + electron-builder --<os> automatically.
yarn build:unpackOutput: dist/<...>/linux-unpacked/ (or platform equivalent). Quickest
way to launch the app from a build for smoke testing.
yarn typecheck # both Node + Web tsconfigs
yarn typecheck:node
yarn typecheck:webyarn lint # ESLint with --fix
yarn format # Prettier write
yarn format-check # Prettier check onlyyarn test # Node's built-in test runner over src/**/*.test.tsHydra is an Electron app with three language runtimes coordinated at startup. A high-level boot sequence:
┌──────────────────────────────────────────────────────────────────┐
│ electron-vite build │
│ │
│ src/main ──► out/main/index.js (Node, Electron main) │
│ src/preload ──► out/preload/index.js (Node, sandbox bridge)│
│ src/renderer ──► out/renderer/... (React, Chromium) │
│ src/big-picture ─► out/big-picture/... (React, full-screen) │
└──────────────────────────────────────────────────────────────────┘
At runtime (per process):
Electron main process
│
├── Loads src/main/main.ts (Chromium window + IPC wiring)
│
├── Spawns Python sidecar python_rpc/main.py
│ └── libtorrent session + JSON-RPC over stdin/stdout
│ (stdin: requests, stdout: responses)
│
├── dlopen native/hydra-native/hydra-native.node (NAPI)
│ └── image format decode, MIME guess, sysinfo, disk space
│
├── Spawns Rust helper at native/hydra-native if napi path differs
│
└── Wires up preload scripts as `contextBridge`s for the renderer.
| Process | Code | Lives in | What it does |
|---|---|---|---|
| Main | src/main/ |
Electron Node | Window lifecycle, system integration, file I/O, IPC, native addon, spawns Python sidecar. |
| Preload | src/preload/ |
Electron sandbox | Sandboxed bridge exposing a typed API to the renderer via contextBridge. |
| Renderer | src/renderer/src/ |
Chromium | React 18 UI, Redux Toolkit store, React Router, i18next (13+ locales). |
| Big-Picture | src/big-picture/ |
Chromium (separate window) | Full-screen controller-friendly UI; CSS scoped to avoid colliding with the main renderer. |
| Python RPC | python_rpc/ |
Subprocess | libtorrent-backed torrent engine. JSON-RPC over stdio; password-protected by a per-launch secret. |
| Native (Rust) | native/hydra-native/ |
.node addon |
Image decoding (gif/jpeg/png/webp, no default features), MIME type guess, sysinfo, disk usage, UUID v4. |
Compiled by napi-build (build.rs) into a cdylib. The NAPI version
target is napi-derive 3.x with feature napi8 and a Tokio runtime. It
is consumed from src/main/services/native-addon.ts (fallback path) and
spun up before any torrent work starts.
- Boots with
parse_cli_args(sys.argv)expecting at least[torrent_port, rpc_password, initial_download_json, initial_seeding_json](or the legacy 6-arg form). - Creates a single
lt.session(...)bound to0.0.0.0:<torrent_port>. - Exposes four RPC methods over stdio JSON-RPC:
status,seed_status,torrent_files,action. - Every request is password-checked with
hmac.compare_digest. - All RPC errors map to a stable string code (
invalid_magnet,metadata_timeout,too_many_files,internal_error, …) so the Node side can branch on the code without parsing tracebacks. - For releases,
python3 setup.py build(viacx_Freeze) produces a folderhydra-python-rpc/containing a free-standing executable — that folder is whatelectron-builder.ymlships asextraResources.
- State: Redux Toolkit (
@reduxjs/toolkit,react-redux). - Routing: React Router v6.
- Forms:
react-hook-form+yup. - Server state:
axioswith cookie-jar support for Hydra Cloud. - i18n:
i18next+react-i18next+i18next-browser-languagedetector; 13+ locales undersrc/locales/<lang>/translation.json. - Drag-and-drop: Atlassian Pragmatic DnD.
- Rich text: TipTap.
- Icons: Phosphor, Lucide, Octicons.
- Charts / graph: Recharts.
- Virtualization: TanStack Virtual,
rc-virtual-list. - Carousel: Embla.
- Streaming:
hls.jsfor video; confetti for celebration animations.
src/main/services/ contains one module per concern. Notable ones:
hydra-api.ts— typed client for the Hydra Cloud REST API.python-rpc.ts— stdio JSON-RPC client wrapping the Python sidecar.native-addon.ts— load + fallback for the Rust addon.download-orchestrator.ts— coordinates torrent + Real-Debrid + Torbox- common redistributables.
umu.ts— Linux Proton launcher (callsbinaries/umu/umu-run).wine.ts— Wine helpers for launching Windows games on macOS/Linux.ludusavi.ts— game-save backup integration (ludusavi/config.yaml).cloud-sync.ts— push save state to Hydra Cloud.steam.ts,decky-plugin.ts— Steam integration.update-manager.ts— auto-update logic (electron-updater).window-manager.ts— multi-window orchestration.
- Ludusavi config (
ludusavi/config.yaml) — shipped so users don't have to downloadludusaviseparately on first launch. Bundled into the installer viaextraResources. - Steam shortcuts — uses
@hydralauncher/steam-shortcut-editor(forked highlight module on Steam). - Sentry — wired in via
@sentry/reactfor renderer telemetry. - Real-Debrid / Torbox — optional debrid providers, configured via
referral IDs in
.env.
Hydra reads backend endpoints from a local .env (gitignored — copy
.env.example and fill in). Vite injects the following keys at build time;
they're hard-coded into the packaged binary, so changing .env after a
build has no effect on existing installations:
MAIN_VITE_API_URL,MAIN_VITE_NIMBUS_API_URL— primary Hydra Cloud API.MAIN_VITE_AUTH_URL,MAIN_VITE_CHECKOUT_URL— auth + storefront flows.MAIN_VITE_WS_URL— realtime gateway (used viawss://).MAIN_VITE_LAUNCHER_SUBDOMAIN,RENDERER_VITE_SENTRY_DSN,RENDERER_VITE_REAL_DEBRID_REFERRAL_ID,RENDERER_VITE_TORBOX_REFERRAL_CODE— misc.RENDERER_VITE_EXTERNAL_RESOURCES_URL— base URL for the static catalogue JSONs (steam-genres.json,steam-publishers.json, etc. insrc/renderer/src/hooks/use-catalogue.ts).
⚠ API host migration (as of 2026-07-06): the original
*.losbroxas.xyzhostnames (hydra-api.losbroxas.xyz,hydra-auth.losbroxas.xyz,hydra-checkout.losbroxas.xyz,api-gateway.losbroxas.xyz,hydra.losbroxas.xyz) all return NXDOMAIN from this network. After verifying reachability in a browser:
- ✅
MAIN_VITE_API_URL/NIMBUS→https://hydra-api-us-east-1.losbroxas.org(returns clean JSON 404 on/)- ✅
MAIN_VITE_AUTH_URL→https://auth.hydralauncher.gg(loads the sign-in page)- ⚠
MAIN_VITE_CHECKOUT_URL→ stillhttps://hydra-checkout.losbroxas.xyz. Verify in a browser before patching.- ⚠
MAIN_VITE_WS_URL→ stillhttps://api-gateway.losbroxas.xyz/realtime. Verify in a browser before patching.- ⚠
RENDERER_VITE_EXTERNAL_RESOURCES_URL→ currently a placeholder pointed athttps://hydra-api-us-east-1.losbroxas.orgas a safer fallback (returns a JSON 404 rather than following the asset-CDN 302 to GitHub HTML). Replace once the real assets CDN URL is confirmed.If you fork this repo and see an empty Home / Catalogue after a fresh rebuild, the first thing to check is whether the hostnames in your
.envstill resolve. The.env.exampletemplate is intentionally left blank on upstream — the official builds inject values at packaging time.
hydra/
├── src/
│ ├── main/ # Electron main process (Node)
│ │ ├── main.ts # entry, window + IPC boot
│ │ ├── services/ # one file per concern (torrent, umu, ludusavi, …)
│ │ ├── helpers/ # small utilities
│ │ ├── events/ # IPC event names + payloads
│ │ └── level/ # embedded leveldb (classic-level) usage
│ ├── preload/ # sandboxed contextBridge API
│ ├── renderer/ # React 18 UI + Redux store
│ ├── big-picture/ # controller-friendly full-screen UI
│ ├── shared/ # code used by both main & renderer
│ ├── locales/ # i18n JSON, one folder per language
│ └── types/ # TS-only types shared across processes
├── python_rpc/ # Python sidecar (libtorrent, cx_Freeze)
│ ├── main.py
│ ├── torrent_downloader.py
│ └── setup.py
├── native/hydra-native/ # Rust NAPI addon (cdylib → .node)
│ ├── src/lib.rs
│ └── Cargo.toml
├── ludusavi/ # bundled game-save backup tool config
├── resources/ # static assets shipped with the app
├── binaries/ # 7z (win/mac/linux) + umu-run
├── scripts/ # build helpers, register-ts-node, postinstall
├── docs/ # screenshots + design docs
├── build/ # electron-builder icons + resources
└── .github/workflows/ # upstream CI; we don't run it
Upstream contributions go to hydralauncher/hydra.
This fork is not accepting contributions. Open an issue here if a note in this README is wrong and an AI assistant will look at it later (specifically, me, the next time I look at this folder).
For this fork's release process — the tag-driven workflow, the
optional RELEASE_NOTES.md curated-notes override, the opt-out recipe
(empty / truncate, not sed), and the softprops merge-behavior
caveat — see CONTRIBUTING.md. It was written for the
same next maintainer (you, three months from now).
Hydra is licensed under the MIT License.
