- Python 97.9%
- CSS 1.4%
- Shell 0.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
Build Flatpak / flatpak (push) Successful in 2m10s
Both changes come from reusing this workflow for a second app, where the parts that were quietly specific to this one showed up. The runtime was hardcoded to org.gnome.Platform//50 with a comment about GTK4 and libadwaita. That is true here and nowhere else: the other repo builds against freedesktop 25.08 and failed with "Unable to find sdk org.freedesktop.Sdk version 25.08" while GNOME 50 was installed around it. Runtime, runtime-version and sdk are now read from the manifest alongside app-id, unquoting as they go since versions are written '50' or '25.08'. Checked against both manifests: this one resolves to exactly the pair that was hardcoded, so nothing about this build changes. FLATPAK_TITLE gives the published .flatpakrepo a readable name, falling back to the slug. Without it the other app would have lost the title it had from hardcoding one. The two workflows now differ only in vendored dependencies and which test suites run, which is as it should be. |
||
| .forgejo/workflows | ||
| data | ||
| flatpak | ||
| kickclient | ||
| scripts | ||
| tests | ||
| .gitignore | ||
| install.sh | ||
| pytest.ini | ||
| README.md | ||
| run.py | ||
KickClient
A native GTK4 / libadwaita desktop client for watching Kick.com streams on Linux, with live chat and a full-screen HTPC mode you can drive entirely from a remote.
Features
- Browse live channels, categories, search, and the channels you follow
- Watch through libmpv, rendered inside the app with hardware decoding
- Live chat with inline emotes, badges and colour-coded names, over Kick's Pusher websocket
- Send chat once signed in
- HTPC mode (
F11) — a 10-foot interface navigable with arrow keys, Enter and Escape, or an IR remote's media keys - Quality selection across every rendition the stream offers
- Keeps the screen awake while a stream is playing
Viewing works without signing in. A Kick account is only needed to see your followed channels and to send chat messages.
Requirements
Arch / CachyOS:
sudo pacman -S gtk4 libadwaita mpv webkitgtk-6.0 python-gobject
Python dependencies are installed into a local virtualenv by the installer.
Install
./install.sh
This creates .venv/, installs a kickclient launcher into ~/.local/bin, and
registers the desktop entry and icon.
Usage
kickclient
kickclient xqc
kickclient --htpc
A channel slug, a full kick.com/<channel> URL, or a kick: URI all work.
Signing in
Menu → Sign in. Kick's real site opens in an embedded browser view; sign in exactly as you would in a browser, including two-factor if you have it enabled. The app never sees or handles your password — it reads only the session cookie Kick sets afterwards, and stores that in your system keyring. The window closes itself once the session is captured.
If the page shows "Oops, something went wrong" — click the account icon in Kick's own header (top right) and sign in from there. This is Kick's error boundary tripping on the freshly loaded page, not a fault in this client: the site's header keeps working, and navigating from it lands on a working sign-in form. Sometimes the page also recovers on its own after ~30 seconds, and the reload button in the title bar retries.
/loginis affected identically, so the homepage is loaded deliberately — its header is the reliable route in.
Remote / keyboard controls
| Key | Action |
|---|---|
| Arrows | Navigate the grid |
| Enter | Open the focused channel |
| Escape / Backspace | Back, or leave HTPC mode |
| Space / Play | Pause and resume |
C |
Show or hide chat |
I |
Show stream info |
M / Mute |
Mute |
+ / − / Volume keys |
Volume |
| Page Up/Down, Prev/Next | Previous or next channel |
F11 |
Enter or leave HTPC mode |
IR remotes that emit the standard XF86Audio* media keys work without configuration.
Configuration
Settings live in a SQLite database at
~/.local/share/kickclient/kickclient.db and are edited from the Preferences
window (Ctrl+,) — there are no environment variables to set. Credentials are kept
in the system keyring, never in that database.
Development
.venv/bin/python -m pytest tests/ -q
The scripts/ directory holds verification harnesses that run against the live
site — smoke_api.py, smoke_chat.py, smoke_player.py, smoke_app.py
(add --htpc), and smoke_login.py (--check / --logout).
How it works
Kick's official public API cannot drive a viewer client: it exposes no playback URLs, cannot read chat, and delivers events only by webhook. This client therefore uses the same internal endpoints the Kick website itself calls.
- Playback is standard AWS IVS HLS with no DRM. The signed URL carries a token that expires after roughly four hours, so it is refreshed automatically mid-session.
- Chat reading needs no authentication. The Pusher app key is discovered at runtime rather than hardcoded, because Kick rotates it.
- All HTTP goes through one swappable session layer, so browser TLS impersonation can be enabled from Preferences if Kick's bot protection ever tightens.
A note on Kick's Terms of Service
Kick's terms prohibit accessing the service "through any technology or means other than those provided or authorized," and this client is by definition a third-party means. In practice the risk is to your account, not a legal one, and it rises if you distribute modified builds. This project is intended for personal use.
It deliberately does not automate past any bot challenge: signing in happens in a real browser engine, driven by you.