|
Some checks are pending
Build Windows Executable / Build BetterCurseForge.exe (push) Waiting to run
|
||
|---|---|---|
| .github/workflows | ||
| assets | ||
| bettercf | ||
| docs | ||
| patcher | ||
| .gitignore | ||
| BetterCurseForge.spec | ||
| LICENSE | ||
| README.md | ||
BetterCurseForge
A patch for the CurseForge launcher on Windows. It blocks ads, adds a theme and plugin system, unlocks the subscriber-only skins, and re-applies itself after CurseForge updates.
What it does
- Ad blocking. Requests to the Overwolf, Adrta and DoubleClick ad servers are blocked at the Electron session level, and some CSS collapses whatever empty ad frames and banners are left. Ad elements are hidden, not removed from the DOM, because removing them breaks React and causes
insertBeforeerrors. - Themes. Themes show up in the launcher's own Settings > Themes page. CSS is injected live, so you don't need to restart to see changes. One theme is included, Purple Night.
- Subscriber skins. The official skins that normally need a CurseForge subscription (PixelForge, LifeForge, FantasyForge, Halloween and the rest) are unlocked.
- Plugins. Plugins are small JS modules with
onEnableandonDisablehooks, scoped styling, and IPC to the main process. There's a sample one called Compact Mode. - Updates. When CurseForge updates itself, the patch gets re-applied automatically. More on that below.
Install
- Download
BetterCurseForge.exefrom Releases. - Run it and click Patch CurseForge.
- Start CurseForge as usual.
It also works from PowerShell or Command Prompt:
# show patch and watcher status
.\BetterCurseForge.exe status
# apply the patch
.\BetterCurseForge.exe patch
# go back to stock CurseForge
.\BetterCurseForge.exe unpatch
# run the background watcher in the foreground
.\BetterCurseForge.exe watch
# open the splash updater by hand
.\BetterCurseForge.exe --repatch-splash
How the repatch works
When CurseForge downloads an update, the Overwolf installer overwrites resources/app.asar with a stock copy and relaunches CurseForge.exe. That undoes the patch, and the unpatched launcher would normally appear on screen. BetterCurseForge deals with it like this:
A small watcher process sits in the background and watches CurseForge's install directory. When it sees an update or an unpatched app.asar, it polls for a new CurseForge.exe every 150 ms and kills the one the installer starts, so the vanilla launcher never gets drawn. Then it opens a splash window with a progress bar and runs the repatch.
The repatch unpacks and repacks app.asar using the Node runtime that ships inside CurseForge (ELECTRON_RUN_AS_NODE=1), so it needs no internet connection and no separate Node install. It takes a few seconds. It also updates the OWEASARSIG integrity signature stored in CurseForge.exe to match the new archive. When that's done, CurseForge relaunches.
Two named Windows mutexes, BetterCurseForgePatchMutex and BetterCurseForgeSplashMutex, stop two patch runs or two splash windows from happening at the same time.
Themes and plugins
Everything user-facing lives in %APPDATA%\CurseForge\BetterCurseForge\:
themes/
purple-night.css
purple-night.json
plugins/
compact-mode/
manifest.json
index.js
The GUI has Open Themes Folder and Open Plugins Folder buttons if you don't want to dig for it.
Writing a theme
A theme is a CSS file plus a JSON manifest with the same name. For example, themes/my-theme.json:
{
"name": "My Theme",
"description": "Custom color theme for CurseForge",
"author": "Your Name",
"version": "1.0.0",
"css": "my-theme.css"
}
and themes/my-theme.css:
:root {
--surface-brand-brand: #10b981 !important;
--surface-brand-brand-hover: #059669 !important;
}
Writing a plugin
A plugin lives in its own subfolder in plugins/<plugin-name>/ with a manifest.json, an index.js, and an optional companion styles.css.
plugins/my-plugin/manifest.json:
{
"name": "My Plugin",
"description": "Custom tweak for CurseForge",
"version": "1.0.0",
"author": "Your Name",
"main": "index.js",
"styles": "styles.css"
}
plugins/my-plugin/index.js:
// Plugins run inside the Electron renderer with access to BetterCurseForge
const { injectCSS, patcher, settings, on, off } = BetterCurseForge;
console.log("My plugin loaded");
// Cleanup when toggled off
plugin.onDisable = () => {
console.log("My plugin disabled");
};
What plugins can do
- UI & DOM tweaks. Inject custom buttons, badges, links, or panels into CurseForge using standard DOM APIs. If a
styles.cssis present in the plugin folder, it is automatically injected when enabled and removed when disabled. - Method patching. Intercept, modify, or override internal JavaScript functions with
BetterCurseForge.patcher.before(),after(), orinstead(). - Persistent settings. Store and read user preferences across restarts using
BetterCurseForge.settings.get(key)andset(key, value). - Event listening. Hook into application lifecycle events using
BetterCurseForge.on(event, callback).
Building from source
You need Windows 10 or 11 and Python 3.10+. Node.js 20+ is only needed if you want to run the docs site.
git clone https://github.com/tomasalias/BetterCurseForge.git
cd BetterCurseForge
python -m pip install pyinstaller
python -m PyInstaller BetterCurseForge.spec --noconfirm
The executable ends up in dist/BetterCurseForge.exe.
Syncing changes from GitHub
To pull down updates made on GitHub:
git pull origin master
If you have local changes that conflict:
git stash
git pull origin master
git stash pop
To push your local changes to GitHub:
git add .
git commit -m "Description of changes"
git push origin master
To run the VitePress docs locally:
cd docs
npm install
npm run dev
License
MIT.
CurseForge and Overwolf are trademarks of their respective owners. This is an independent open-source project and isn't affiliated with or endorsed by either of them.