Note
Discord RPC by ArnavK-09 is GNOME Shell extension that lets you customize and broadcast your Discord Rich Presence directly from the quick settings panel β pick an activity type, set a title & caption, toggle images and the elapsed timer, and turn broadcasting on/off with one click. Everything is event-driven and non-blocking: no background daemon, no polling loops, minimal resources, and it survives hard poweroffs cleanly.
- Quick-settings tile β A native
QuickMenuTogglewithtoggleModeso you flip broadcasting on/off right from the system menu; the arrow opens a compact popup. - Compact popup β Activity type grid (Playing / Listening / Watching / Competing), editable Title (sent as
activity.name, replacing the app name) and Caption (activity.state), and an "Advanced settings" button. GNOME theme colors + accent highlight, no custom palette. - Advanced preferences β Adw-based window for Client ID, activity type, Title/Caption, Show elapsed time + Reset timestamp, Show images + large/small asset keys & hover text, Clear on disable, and Only show when Discord is open.
- Only show when Discord is open β Hides the tile unless a live Discord IPC socket is detected (event-driven
GFileMonitor+ async probe, no busy polling). - Crash-free & leak-free β Every timer, signal, and monitor is torn down in
disable(); async ops are guarded so they no-op after destroy.
git clone https://github.com/ArnavK-09/discord-rpc-gnome-extension.git ~/.local/share/gnome-shell/extensions/discord-rpc-arnavk09@ArnavK-09 && cd ~/.local/share/gnome-shell/extensions/discord-rpc-arnavk09@ArnavK-09 && glib-compile-schemas schemas/ && gnome-extensions enable discord-rpc-arnavk09@ArnavK-09pack into zip
zip -r discord-rpc-arnavk09@ArnavK-09.zip . -x "*.git*" -x ".github/*" -x "screenshots/*" -x "README.md" -x "package.json" -x "LICENSE" -x "*.ox*" -x ".gitignore" -x "node_modules/*" -x ".*"
Then log out and back in (or restart the Shell) so GNOME loads the extension, and set your Client ID in Preferences (from the Discord Developer Portal). Start Discord to broadcast.
| Layer | Technology |
|---|---|
| Runtime | GJS (ES modules) inside GNOME Shell |
| UI (shell) | St, Clutter, GObject signals, QuickSettings API |
| UI (prefs) | libadwaita (Adw), GTK4 |
| Settings | GSettings / dconf (org.gnome.shell.extensions.discord-rpc) |
| Network | Discord local RPC over Unix socket (discord-ipc-{0..9}) |
| Tooling | Bun, oxfmt, oxlint |
Discord RPC talks to the Discord desktop client over its local IPC socket (
$XDG_RUNTIME_DIR/discord-ipc-N) β no gateway, no bot token, no external daemon.
- Connect β
lib/discordIpc.jsopens the Unix socket with asyncGio.SocketClient.connect_async()(non-blocking), tries each candidate path with a fresh cancellable, and performs the Discord RPC handshake (op 0,{ v: 1, client_id }). - Handshake β READY β on
op 1READY, the IPC emitsconnected. - Broadcast β
lib/controller.jsbuilds the activity (name,state,assets,timestamps) and sendsSET_ACTIVITY(op 1) frames as single-byte little-endian-header + JSON payloads via asyncwrite_all_async. Edits are debounced so typing doesn't flood Discord. - React β all preferences are GSettings keys; the controller observes
changed::keyand re-pushes instantly. The quick-settings tile bindscheckedβenabled. - Detect Discord β
lib/watcher.jsuses an event-drivenGFileMonitor+ a 5s async probe to know whether Discord is running, so "Only show when Discord is open" hides the tile when it isn't. - Clean lifecycle β
disable()disconnects every signal, removes everyGLibsource and monitor, and destroys all widgets; async ops are guarded by a_destroyed/_openGengeneration flag so in-flight work aborts safely instead of touching freed objects.
Here's a working and expected screenshot of Discord RPC
![]() |
![]() |
| Quick settings tile β toggle broadcasting on/off | Preferences β client ID, activity, assets, behavior |
-
Fork the Repository
Click the Fork button at the top-right of the repo page. -
Clone Your Fork
Clone the repo locally:git clone https://github.com/ArnavK-09/discord-rpc-gnome-extension.git
-
Create a Branch
Create a new branch for your changes:git checkout -b your-feature-branch
-
Make Changes
Implement your changes (bug fixes, features, etc.). Format & lint before committing:bun run format && bun run lint -
Commit and Push
Commit your changes and push the branch:git commit -m "feat(scope): description" git push origin your-feature-branch -
Open a Pull Request
Open a PR with a detailed description of your changes. -
Collaborate and Merge
The mastertainers will review your PR, request changes if needed, and merge it once approved.
Found a bug or need help? Please create an issue on the GitHub repository with a detailed description.
![]() |
Discord RPC is licensed under the Unlicense License. See the LICENSE file for more details.
π If you find this project helpful, please give it a star on GitHub! π


