What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
The synchronizer keeps extension counts and version numbers aligned across the Visual Studio Marketplace, Open VSX, a portfolio page, and repository documentation by running two paths against one normalized data model. Visitors’ browsers refresh the portfolio page from the registries but reuse cached values for 24 hours. A Node script, run by a daily scheduled CI job, rewrites the static HTML and README fallbacks and commits only when the output has changed.
This is the author’s own implementation for seven extensions in the dotUniverse portfolio, described in a DEV Community article by freerave published September 28, 2026: Building an Automated, API-Driven Stats & Version Synchronizer for VS Code Extensions with 24-Hour Smart Caching. The code paths, the cache interval, and the sample totals below are reported from that article. They have not been independently tested, and the registry behaviour they rely on is not covered by a published guarantee.
As an Amazon Associate I earn from qualifying purchases.
The maintenance work this removes
The author lists three recurring chores: logging into several web dashboards, adding per-registry counts by hand, and editing HTML cards, version badges, and README tables one at a time. The design answers all three with a single data model. Each extension is identified once, its statistics and latest version are fetched from each registry, and the same normalized result feeds the live page, the static page, and the README.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteTwo registries, two different count labels
The two stores do not expose the same kind of number, and the implementation depends on that difference. Before combining them on any page, check what each field means.
#1 Best Overall
| Aspect | Visual Studio Marketplace | Open VSX |
|---|---|---|
| Request shape | One POST to https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery with criteria for several extension IDs and flags requesting statistics, versions, and metadata |
One request per extension to https://open-vsx.org/api/{namespace}/{extension} |
| Fields the sync reads | install and downloadCount from the statistics array, plus the first returned version |
downloadCount and version |
| Label in the example output | “installs” | “downloads” |
| Value shown on the page | Math.round((install || 0) + (downloadCount || 0)) |
downloadCount as returned |
| Official guarantee of the page formula | Not stated. The author compared the result with the Marketplace “Installs” figure for seven extensions and reports a match. | Not stated in the author’s account |
| Entries without a registry identifier | Not described | Skipped |
The Marketplace display total
The Marketplace sample maps the returned statistics by name and keys each result by the lowercase extension name. It then adds the install and downloadCount values, treating a missing value as zero. The author’s cross-check against the Marketplace UI covered seven extensions. That is an observation about how the figures lined up in those cases, not a documented contract about what the API fields mean or how they will behave over time. Re-verify the formula against current responses before you rely on it.
Combining the two registries
A portfolio-wide headline can add the Marketplace and Open VSX values, but it should be labelled as a total of registry-reported figures from two stores. It is not a count of unique people or unique installations. The author’s example total is 19,502, made up of 4,401 Marketplace and 15,101 Open VSX in one sample terminal output. That is a snapshot from the author’s run, not a current live figure.
Rank #2
The browser path: show cached values first
The extension-stats.js module runs in the visitor’s browser and works in this order:
Free tools Windows power users keep installed
One-click scans. No signup required.
- Read the
localStoragekeydotuniverse_ext_stats_v1when the page initializes. - If cached values exist, apply them to the page immediately, so the visitor sees numbers without waiting for a network request and the text does not flicker.
- Compare the stored timestamp with the cache TTL, defined as
24 * 60 * 60 * 1000milliseconds. - If no cache exists, or the timestamp is older than the TTL, request fresh data from both registries.
- When a request completes, write the fresh values over the cached baseline and store them with a new timestamp.
Each update targets an element tagged with a data-ext-name attribute on the extension card. The module updates the version, each store badge, and the portfolio total from that same normalized record. The author’s reason for the 24-hour interval is practical: tools tend to ship over days or weeks, and a daily refresh cuts repeat requests while keeping the figures reasonably current. It is a design choice for this portfolio, not a measured optimum.
The repository path: a daily script with a commit guard
The repository path exists because the browser module does not help anyone who reads the HTML or README without running JavaScript, including many search crawlers. The static fallback values therefore have to be regenerated on a schedule.
The sync script
scripts/sync-extension-stats.mjs fetches current metrics, updates index.html and README.md, and prints a terminal summary of what it found. The script is the only writer for those static values, which keeps the fallbacks consistent with the live page’s data model.
Rank #4
The scheduled job
- Trigger the job with the cron expression
0 0 * * *, which runs daily at midnight UTC. - Allow a manual run as well, so you can refresh the values outside the schedule.
- Set up Node.js 20 in the job. This is the author’s example configuration, not a general requirement.
- Run the sync script.
- Stage the generated files.
- Check whether the staged diff is empty. A common way to do this is
git diff --cached --quiet, which exits with status 0 when nothing is staged. - Commit and push only when the diff is not empty.
The guard matters because a daily job that always commits would fill the history with no-op changes on days when no counts moved. The job also needs write permission on the repository and a commit identity, both of which the workflow must provide.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →What the official publishing docs add
Microsoft’s extension publishing guide describes vsce as the command-line tool for packaging, publishing, and managing extensions, and documents SemVer-compatible version increments such as vsce publish minor. It also describes the publisher management page on the Marketplace, which gives access to statistics for each extension. In the guide’s words, the page “gives you access to each extension’s Acquisition Trend over time, as well as Total Acquisition counts and Ratings & Reviews.” The guide is at Publishing Extensions | Visual Studio Code Extension API.
Microsoft’s extension documentation also separates two lifecycle actions that matter for a synchronizer. Unpublishing keeps an extension’s statistics and leaves it reachable through an existing API. Removing an extension deletes its statistics. If an extension in the configuration is unpublished, the sync will still find it, but if it is removed, its entry will return no statistics and the script needs a way to handle that.
Failure modes and what to check
- Stale values: a visitor can see cached numbers for up to the full 24-hour TTL before a refresh begins.
- Partial failures: the author describes handling each request’s failure separately, so one failed Open VSX lookup does not discard the other results. The article does not describe what the page shows for the failed extension, so test that case before you deploy.
- Missing identifiers: Open VSX entries without an identifier are skipped, which means their counts drop out of the total.
- Cross-origin access: the author reports that both APIs accept browser requests. That is the author’s experience, not a published policy, and it can change.
- Unchanged days: if the staged diff check is missing or broken, the daily job creates a commit every day.
Adapting the pattern to your own extensions
- List each extension by its Marketplace publisher and name, and by its Open VSX namespace and name, and map both to one record.
- Decide the label for each store’s count. Use “installs” only for the field the Marketplace actually returns, and “downloads” for Open VSX.
- Choose a cache interval for your release cadence. Twenty-four hours suited the author’s tools, but a faster-moving project may want a shorter one.
- Put the static fallback values into HTML and README through one script, and make that script the only place they are written.
- Add the commit guard before enabling the schedule, and run the job manually once to confirm it produces no commit when nothing has changed.
”
The Bottom Line
The pattern works best when the browser and the repository share one normalized record and one cache interval, and when the total labelled as a combined registry figure is never presented as unique installs. Treat the Marketplace formula and the cross-origin behaviour as implementation details to re-check against current responses, not as guaranteed platform behaviour.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools




