Hey y’all! I’m Jagath Ramayanapu (Shyam) from India, and I’m a GNOME GSoC intern this year. This summer, I’m working on bringing app uninstallation directly to the GNOME Shell App Grid.
Previously, to remove an app in GNOME, you had to open GNOME Software, find the app, and click Uninstall. With this feature, users will soon be able to uninstall apps directly from the App Grid’s context menu.
This is the first of a two-part blog on how we are building this feature. In this post, we’ll cover the changes in GNOME Shell’s JavaScript that make it possible.
The Problem: Talking to the App Store
GNOME Shell is great at drawing your desktop, but it actually has no idea how to delete an app or clean up user data. To do that, it needs to ask a App Store like GNOME Software to do the heavy lifting.
To solve this, we created a d-bus interface called AppStoreIntegration. You can think of it as a dedicated middleman whose only job is to talk to GNOME Software in the background.
We designed this helper with a few key goals in mind:
At first, I planned to have GNOME Software own this interface. However, that would have tightly coupled the feature to GNOME Software. Based on feedback from my mentor, Adrian Vovk, I moved the ownership of AppStoreIntegration into GNOME Shell instead.
This design makes the interface app store agnostic. Any app store can implement the interface, allowing GNOME Shell to work with different app stores without depending on a specific one.
This interface has two methods :
2. UninstallApp :
Now that we had our D-Bus contract, we built a helper module in GNOME Shell called js/ui/appStoreIntegration.js Inside this file, we built a class called AppStoreIntegrationManager whose sole purpose is to call those two D-Bus methods.
We designed this manager with a few key goals:
Once we had the cached data, we needed to update the UI in js/ui/appMenu.js.
We added a new “Uninstall” button to the right-click menu, but we had to be careful. We don’t want to show an “Uninstall” button for apps you aren’t allowed to remove (like core system apps).
To fix this, we tied the menu directly to our new manager using reactive signals. Every time you open the menu, a function called _updateUninstallItem runs. It asks the manager: appStoreIntegrationManager.canUninstall(appId). If the answer is false, the button completely hides itself.
Handling the User InteractionUninstalling an app isn’t always as simple as deleting a folder. Modern software, like Flatpaks, often leaves behind saved files and personal configurations. We wanted to give users the option to clean up this data, but only if the app store actually supports it.
When you click Uninstall in the right-click menu, the UI triggers a smooth, step-by-step interactive flow:
Building this feature was a fantastic learning experience in bridging different parts of the GNOME ecosystem. A huge thanks to Adrian for mentoring me throughout this project and helping me navigate the architecture.
If you’d like to check out the changes, here’s my MR.
If you run a homelab, you’ve inevitably run into the absolute nightmare that is CGNAT (Carrier-Grade NAT) or strict corporate firewalls. You have a server at home that you want to SSH into, but your ISP doesn’t give you a public IP address. Or maybe you’re at a coffee shop or behind a strict corporate firewall that blocks all outbound SSH connections.
Traditionally, the solutions are:
What if there was a completely decentralised, free, open-source network of relays already spanning the globe that we could hijack to establish direct, multiplexed, end-to-end encrypted tunnels between any two machines without any accounts or infrastructure?
Enter syncthing-socket and the Syncthing global relay network.
The Syncthing Relay NetworkSyncthing is an incredible peer-to-peer file synchronisation tool. To ensure files sync even when both devices are behind strict NATs, the Syncthing community operates a global network of public relays and discovery servers.
These servers are completely open and decentralised. They don’t care what data is being transmitted—they just facilitate STUN/TURN WebRTC connections to punch through NATs.
I vibe-coded syncthing-socket as a standalone, lightweight Go daemon that securely hijacks this exact network to pipe raw TCP sockets, PTY shells, and HTTP proxies!
How syncthing-socket WorksUnder the hood, syncthing-socket imports the official Syncthing protocol libraries but throws away the file-syncing logic. Instead, it uses the peer-to-peer WebRTC connection to multiplex raw byte streams using Yamux.
When you start the server, it deterministically generates a Syncthing Device ID from a passphrase and connects to the global relay pool:
$ ./syncthing-socket server --passphrase "my-super-secret" --forward 127.0.0.1:22This server is now securely listening on the decentralised Syncthing network. The discovery servers know how to route to it, but nobody can connect unless they have the mathematically paired client passphrase.
From anywhere in the world, on any network, you run:
$ ssh -o ProxyCommand="./syncthing-socket client --passphrase 'my-super-secret'" user@ignored_hostsyncthing-socket will instantly negotiate a WebRTC STUN/TURN connection via the nearest public relay, establish a direct end-to-end encrypted P2P tunnel, and pipe your SSH connection perfectly through it. If a direct P2P connection isn’t possible, it gracefully falls back to using the relay server as a TURN proxy.
Beyond SSH: SOCKS5 and PTY ShellsBecause we established a fully multiplexed Yamux tunnel over WebRTC, we can do much more than just pipe a single TCP socket.
Native PTY Shells:
You can completely drop sshd and use syncthing-socket natively!
This spawns a remote bash session and pipes your raw local terminal directly into it. It natively supports tab-completion, vim, htop, and even transmits window resizing events (SIGWINCH) over a dedicated control stream so the remote UI always perfectly fits your screen.
Remote SOCKS5 Proxy:
Want to browse the web through your homelab’s internet connection securely?
Just point your browser to socks5://127.0.0.1:1080 and you’re fully proxying your web traffic over an encrypted, decentralised P2P tunnel.
ConclusionBy standing on the shoulders of the incredible Syncthing project, syncthing-socket provides a zero-config, zero-infrastructure, completely decentralised way to punch through CGNATs and firewalls.
Similar ProjectsWhile syncthing-socket fills a specific niche, it’s worth mentioning similar tools in this space. For raw socket routing, there’s gsocket and its clone minisocket. If you just want to share a terminal, tmate (though largely defunct) was a pioneer. For full remote desktop access, solutions like RustDesk, AnyDesk, and TeamViewer exist. In terms of underlying architecture, Magic-Wormhole uses a very similar P2P approach (with a modern Rust replacement being Iroh).
Check out the code on GitHub and take back control of your homelab connectivity!
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.