LocalChromeStore
A personal store for the Chromium extensions you build yourself. Lists every extension across your GitHub repos, downloads the latest release ZIP/CRX, and loads them into Chrome / Brave / Edge with a single click. Install. Uninstall. Move on.
LocalChromeStore exists for one reason: when you build a lot of Chrome extensions, "Load unpacked" gets old fast. This is a native Windows store UI for your own extensions — sourced from your GitHub releases, with proper install / uninstall semantics.
Why it exists
Chromium 75+ blocks drag-and-drop install of self-signed CRX files with CRX_REQUIRED_PROOF_MISSING — even with developer mode on, even with a valid signing key. The official paths are:
- Chrome Web Store — useful for shipping, awful for testing your own dogfood
- Load unpacked — works, but clicking through the file picker for ten extensions every browser reset is friction
- Enterprise Policy
ExtensionInstallForcelist— the only self-host path that actually works on stock Chrome / Brave / Edge
LocalChromeStore wraps path 2 with a real store UI and (in v0.2.0) wraps path 3 for true auto-install.
Features
- GitHub-sourced discovery — lists every repo with a
manifest.jsonor a release ZIP / CRX asset for any user or org - Store-style cards — extension logo, name, version, description, install / uninstall buttons, link to repo
- One-click install — downloads the latest release ZIP, extracts to a managed folder, tracks it
- One-click uninstall — wipes the local copy and removes it from the load list
- Browser launcher — fires Chrome / Brave / Edge / Vivaldi / Opera / Chromium with
--load-extension=...pointing at every installed extension - Auditable launch sessions — optional startup URL, clean temporary profile mode, and a copyable launch command preview
- Environment portability — export/import installed extension targets and portable discovery settings as JSON
- Update workflow — update-available badges, permission-change review, manual Update all, optional auto-update on refresh, and optional launch-after-install
- Search and filter — by name, repo, or description; toggle to show only installed
- Topic filter (optional) — restrict discovery to repos tagged with a specific GitHub topic (default
chrome-extension) - Optional GitHub PAT — unauthenticated GitHub API caps at 60 req/h; a personal access token raises that to 5,000/h, unlocks private repos, and is stored with Windows DPAPI
- Catppuccin Mocha dark theme — easy on the eyes; light theme planned
- Activity log + crash log — every install / uninstall / launch is logged in-app and to disk
- Async — every API call, download, and extraction runs off the UI thread
Install
From release (recommended)
- Grab the latest
LocalChromeStore-vX.Y.Z.zipfrom the Releases page - Extract anywhere
- Run
LocalChromeStore.exe
Requires the .NET 9 Desktop Runtime (the installer prompts if missing).
From source
git clone https://github.com/SysAdminDoc/LocalChromeStore.git
cd LocalChromeStore
dotnet build src/LocalChromeStore/LocalChromeStore.csproj -c Release
dotnet test LocalChromeStore.sln -c Release
./src/LocalChromeStore/bin/Release/net9.0-windows/LocalChromeStore.exe
Usage
- Click Settings in the top right
- Set GitHub user / org to your handle (defaults to
SysAdminDoc) - (Optional) Paste a GitHub personal access token to raise rate limits and surface private repos
- (Optional) Enable Filter by topic if you want to limit to repos tagged with
chrome-extension - Click Save settings, then click Refresh
Every qualifying repo appears as a card. Click Install on a card — LocalChromeStore downloads the latest release ZIP/CRX, extracts it to %LOCALAPPDATA%\LocalChromeStore\extensions\<owner>\<repo>\<version>\, and registers it.
When installed extensions have newer catalog versions, their cards show Update available. Use the card's update button for one extension, or Update all to replace every installable outdated local copy. If an update adds required permissions, optional permissions, host access, or optional host access, LocalChromeStore shows the diff and asks for approval first. Auto-update on refresh skips permission-expanding updates so new extension access is not accepted silently.
To load installed extensions into a browser:
- Pick the browser from the dropdown
- (Optional) Enter a startup URL to open after the extensions load
- (Optional) Enable Clean temp profile to launch with an isolated browser profile under
%LOCALAPPDATA%\LocalChromeStore\profiles\temp\ - Click Launch session
The browser opens with --load-extension=<all installed paths>. The browser will show its standard "developer mode extensions" banner — that is normal for --load-extension and not a sign anything is wrong. The extensions persist for that browsing session; close the browser and they unload (which is exactly what you want during dev/test).
Use Copy args to copy the exact command LocalChromeStore will run. This is useful when debugging extension load failures or reproducing a launch session outside the app.
Use Export environment to save the installed extension set, manifest trust snapshot, GitHub owner list, topic filter, and launch options as a portable JSON file. Use Import environment on another machine to apply those discovery settings, refresh GitHub, and install matching ZIP/CRX release assets. If the current catalog release adds permissions compared with the exported snapshot or local installed copy, import asks for approval before installing it. GitHub tokens are never written to the export file.
How discovery works
For each user/org you've configured, LocalChromeStore:
- Lists their repos via the GitHub API
- For each repo, checks for a latest release with a
.zipor.crxasset - If no release asset, probes for
manifest.jsonat common paths (root,extension/,src/,dist/,public/) - If the manifest is found (in the ZIP or repo), reads
name,version,description, andiconsto enrich the card - Caches the icon to
%LOCALAPPDATA%\LocalChromeStore\cache\icons\
Repos with no manifest and no release ZIP/CRX are skipped — they won't clutter the store. Archived repos are skipped too.
Where things live
| Path | Purpose |
|---|---|
%APPDATA%\LocalChromeStore\settings.json |
User settings (GitHub user, DPAPI-protected token, preferred browser, launch/update options) |
%APPDATA%\LocalChromeStore\installed.json |
Installed-extension manifest |
%LOCALAPPDATA%\LocalChromeStore\extensions\<owner>\<repo>\<version>\ |
Extracted extension files |
%LOCALAPPDATA%\LocalChromeStore\profiles\temp\ |
Clean temporary Chromium profiles created for launch sessions |
%LOCALAPPDATA%\LocalChromeStore\cache\icons\ |
Cached extension icons |
%LOCALAPPDATA%\LocalChromeStore\logs\ |
Crash logs |
To start fresh, just delete the two folders.
Architecture
WPF on .NET 9 — MVVM, no third-party MVVM toolkit.
Models/— plain data records (ExtensionInfo,InstalledExtension,BrowserInfo,AppSettings)Services/—GitHubService(Octokit wrapper, discovery),ExtensionService(download, ZIP / CRX extract, install state),BrowserLauncher(browser detection + launch-plan construction),SettingsService(JSON persistence + DPAPI token protection)ViewModels/—MainViewModelorchestrates everything;ExtensionCardViewModelper-card stateViews/—ExtensionCardViewuser control, plus the main windowThemes/— Catppuccin Mocha resource dictionary
CRX files are unpacked by stripping the CRX2/CRX3 header and extracting the inner ZIP — Chrome / Brave / Edge re-sign the unpacked tree on load anyway, so we don't need to verify the signature ourselves.
Roadmap
See ROADMAP.md. Highlights:
- v0.2.0 — Enterprise Policy install path: write
HKLM\Software\Policies\Google\Chrome\ExtensionInstallForcelist(and Brave / Edge equivalents) plus a self-hostedupdate.xmlon GitHub Pages, so extensions auto-install at next browser launch with no--load-extensionflag and no developer-mode banner - v0.3.0 — Update safety: historical-version restore for environment imports, stronger manifest/extraction tests, and policy-ready package checks
- v0.4.0 — Light theme + accent color picker
- v0.5.0 — Local folder source, custom update-feed source, and richer named launch profiles
Contributing
This is built primarily for personal dev/test workflow, but PRs are welcome. Open an issue first if it's a bigger change.
License
MIT.