I've been using Ungoogled Chromium as my daily driver for a while now. The speed is incredible — no telemetry overhead, no background services phoning home, just a lean, fast browser that gets out of your way.
But there's a catch. Actually, several.
The Problem: Extension Management Hell
If you've used Ungoogled Chromium, you know the drill. The Chrome Web Store isn't integrated. You can't just click "Add to Chrome" and have things work. Sites like ungoogledextensions.com are lifesavers — they let you browse and install extensions manually. But the moment you have more than a handful of extensions, things start falling apart.
Here's what happened to me. Twice:
Lost profile — Something corrupted my Chrome profile directory. All extensions gone. I spent an entire evening hunting down extension IDs, opening two dozen Web Store tabs, and clicking through install dialogs one by one.
Accidental removal — I was debugging a browser issue and disabled a few extensions. One slip of the mouse later,
uBlock Originwas uninstalled. I didn't notice for three days. Three days of ads.
After the second incident, I thought: there has to be a better way.
The Idea: Declarative Extension Management
What if I could just write down which extensions I want, and have a tool handle the rest?
cjpalhdlnbpafiamejdnhcphjbkeiagm # uBlock Origin
gcbommkclmclpchllfjekcdonpmejbdp # HTTPS Everywhere
nngceckbapebfimnlniiiahkandclblb # Something else I need
Save the list. Done. The tool installs whatever's missing, removes whatever shouldn't be there, and keeps checking so nothing drifts. If uBlock gets nuked again, it comes back automatically. If I switch machines, I just paste the same list.
That's the stabilizer.
What It Does
I built Ungoogle Extension Stabilizer — a Manifest V3 Chrome extension that acts as a consistency watchdog for your browser extensions.
Core features:
| Feature | How it works |
|---|---|
| Declarative list | Paste extension IDs, one per line. That's your source of truth. |
| Auto-install | Missing extensions are installed via CRX direct download URLs. The stabilizer opens the install page and Chrome handles the rest. |
| Auto-remove | Extensions not in your list? Removed on next sync. No clutter, no surprises. |
| Scheduled checks | Configurable timer (default 30 min). Your browser stays consistent even if you forget about it. |
| Self-healing | Accidentally remove a managed extension? The stabilizer detects it and reinstalls automatically. |
| One-click sync | Open the popup, hit "Sync Now". Full consistency pass in seconds. |
Architecture at a glance:
┌───────────────┐ ┌────────────────────┐ ┌──────────────────┐
│ Popup UI │────▶│ Service Worker │────▶│ Chrome APIs │
│ (user input) │ │ (install/monitor) │ │ management, │
│ │◀────│ │◀────│ storage, alarms │
└───────────────┘ └────────────────────┘ └──────────────────┘
Why CRX Direct Downloads?
The first version tried to automate the Chrome Web Store — injecting scripts to find and click the "Add to Chrome" button. It was fragile. The Web Store's DOM structure changes, shadow DOM makes element selection tricky, and honestly it felt like building on sand.
Then I discovered the CRX direct download URL:
https://clients2.google.com/service/update2/crx
?response=redirect
&prodversion=130.0.0.0
&acceptformat=crx2,crx3
&x=id%3D{EXTENSION_ID}%26uc
Navigating to this URL triggers Chrome's native extension installation flow — no DOM parsing, no button hunting, no fragile selectors. The browser does what it was designed to do. We just need to point it at the right URL.
The User Gesture Challenge
Here's something I learned the hard way: Chrome requires a user gesture for chrome.management.uninstall(). You can't just call it from a service worker and expect it to work. The error message is wonderfully unhelpful:
chrome.management.uninstall requires a user gesture.
The fix? Move uninstall operations to the popup context, where every button click IS a user gesture. Each removal triggers a browser confirmation dialog, and the user's click on "Remove" provides a fresh gesture for the next one. Not perfectly zero-touch, but about as close as Chrome's security model allows.
Getting Started
# Clone the repo
git clone https://github.com/TingyuShare/ungoogle-extension-stabilizer.git
# Open Chrome / Ungoogled Chromium
# Navigate to chrome://extensions
# Enable Developer Mode
# Click "Load unpacked" → select the project folder
Find your extension IDs from the Web Store URL:
https://chromewebstore.google.com/detail/cjpalhdlnbpafiamejdnhcphjbkeiagm
Paste them into the popup, save, and you're done.
What's Next
This is v1.0. There's plenty I want to add:
- Export/import profiles — Share extension lists as JSON or a simple link
- Extension name resolution — Show human-readable names alongside IDs
-
Firefox port — The
browser.managementAPI is similar; a port shouldn't be too involved - Multi-profile support — Different extension sets for work vs. personal browsing
- CLI companion — A Node.js tool that generates the extension list from a config file
Want to Help?
This project is MIT licensed and open to contributions. Whether it's code, bug reports, documentation, or translations — all are welcome.
Check out the repo: github.com/TingyuShare/ungoogle-extension-stabilizer
Some areas where I'd especially love help:
- 🌐 Translations for the popup UI
- 🧪 Testing on different Chromium forks (Brave, Edge, Vivaldi)
- 🎨 UX polish — better status indicators, dark/light theme support
- 📦 CI/CD for automated release packaging
Why This Matters
The Ungoogled Chromium community values independence. No account sync, no cloud profiles, no vendor lock-in. But that independence comes with a maintenance burden. Every extension is your responsibility — install it, update it, keep track of it.
I built this stabilizer because I believe you shouldn't have to choose between privacy and convenience. You should be able to define your browser's identity in a text file and trust that it stays consistent.
If that resonates with you — give the project a ⭐, try it out, or contribute. Let's make extension management boring again.
Built with ❤️ for the ungoogled Chromium community. MIT licensed. View on GitHub →
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.