zotero-plugins: a maintained catalog of Zotero add-ons and their XPI compatibility
【Maintenance Suspended | 暂缓更新】Zotero Plugins Collection | Zotero 插件合集 | Awesome Zotero Plugins
At a glance
- What is it?
- The zotero-chinese/zotero-plugins repository is a TypeScript project that maintains a local catalog of Zotero plugins, collects repository metadata and XPI compatibility data, and publishes it to a website. It is a data pipeline with a shadow mode, a daily source sync and a site that reads from an external scraper.
- Who is it for?
- Adopt zotero-plugins if you are running a Zotero plugin directory or want the XPI compatibility ranges and download links catalogued for you, since the repository does the version detection and source reconciliation work that is tedious to do by hand.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the repository actually is: a catalog plus a collector
The README states the scope in one sentence: this repository maintains a local Zotero plugin catalog and independently collects repository metadata and XPI compatibility information. The published site is at zotero-chinese.com/plugins, and the topics are awesome, plugins, zotero, zotero-addon and zotero-plugin. The interesting part is the split between two data sets. There is a local catalog of plugins the project maintains itself, and there is an external scraper whose output is what the website currently publishes. The primary language is TypeScript, the licence is MIT, the package is private with version 0.0.0 and the package manager is pinned to [email protected]. One thing to notice before anything else: the repository description carries a maintenance suspended notice, while the README says submissions are being accepted again. That tension is the honest summary of the project's state, and it is the first thing to check if you plan to depend on it.
How the catalog is structured and how compatibility is derived
The data model is split across two TypeScript sources. src/plugins.ts contains the active plugins, and src/deprecated.ts retains the legacy ones, and the README is clear that the active and legacy split is preserved deliberately through upstream merges. The compatibility answer comes from the XPI manifests, which determine compatible Zotero versions, listed as 6 through 11. Other fields do specific jobs: assetName selects an attachment, customLink supports external download sources, and tags and recommended preserve upstream metadata. Historical release selectors are combined with the newest stable release from the most recent release page, which is how a plugin that only publishes a rolling download still gets a concrete version. The scale is documented too. On 2026-10-05 the local catalog was reconciled with the upstream addons directory, giving 337 unique repositories compared with 336 published plugins, and the report at reports/source-reconciliation.json lists the additions, the duplicates and the one unpublished source entry.
The collector, and the shadow mode that gates promotion
The collector is the part of the project with real engineering in it, and the rollout mode is the mechanism that keeps it honest. The default shadow build runs the collector and compares its candidate data with the external scraper, while published plugins.json continues to use the external data during validation. Chart collection remains disabled and published charts are preserved. The promotion path has four steps, and each one is a gate. You merge the changes and inspect comparison.json and collector/fetch-report.json in the Actions artifact. You check repository coverage, historical releases, compatibility ranges and download URLs, where fetch failures, missing releases and version regressions block promotion. You then run CI manually with collector-mode: primary to publish independently collected data, optionally setting the repository variable COLLECTOR_MODE=primary to retain that mode for scheduled builds, and reverting to shadow to publish external data again. Finally, the website still reads the external scraper directly, so you switch both plugin data and update timestamps in the website's .github/scripts/fetch-data.mjs after validating the independent output. Unreleased sources absent from the external output are marked pending and do not block promotion, incomplete candidates stay available for inspection, and the collector never creates issues or comments.
The daily source sync and its review gate
A separate workflow handles the upstream source catalog. The .github/workflows/sync-source.yml file runs daily at 05:45 Asia/Shanghai and supports manual dispatch. It merges syt2's source catalog and the latest published snapshot, then creates or updates a pull request on the automation/sync-syt2-sources branch when the catalog changes, and that pull request has to be reviewed and merged to update the collector's sources. The merge retains local-only plugins, repository aliases, historical selectors, verified compatibility corrections and the active and legacy split, while new unpublished sources stay pending. Typecheck, tests and lint run before the pull request is created, and the artifacts record the source commit, the release metadata and the merge report. Two safety details are worth noting. PR creation uses ACCESS_TOKEN when available, falling back to GITHUB_TOKEN, and the fallback needs a repository setting that allows Actions to create pull requests and does not trigger ordinary pull request workflows. And pull requests are never merged automatically, and upstream code is not executed.
The development commands, and the local build
The development section is short, and it uses pnpm from package.json with GITHUB_TOKEN supplied through the environment. The command list covers the full local loop.
pnpm install --frozen-lockfile
pnpm typecheck
pnpm lint:check
pnpm test
COLLECTOR_MODE=shadow pnpm build
pnpm data:compare dist/external-plugins.json dist/collector/plugins.json
pnpm data:sync-source /path/to/scraper-checkout /path/to/addon_infos.json
pnpm lint:fixThe two data commands are the ones worth understanding. The compare script diffs the external output against the collector output, which is the check that stands in for a manual comparison. The sync-source script imports upstream data from a scraper checkout and an addon_infos.json path, and the README tells you to review the diff afterwards because local-only repositories are preserved rather than overwritten. For a quick sample you can set COLLECTOR_REPOS to a comma separated list of owner/repo pairs and COLLECTOR_DIST to a directory such as dist/sample, then run the data:info script. The XPI files themselves are cached in .cache/xpi by asset ID and update time, while custom URLs are refreshed on every run. Candidate data goes to dist/collector, published JSON goes to dist and to the legacy dist/dist paths.
The limits: a catalog with a paused maintenance notice
There are three constraints you should know before adopting this. The first is the maintenance notice in the repository description, which sits in tension with the README's statement that submissions are open again. For a directory that other people link to, that matters more than for a library. The second is that the published site still reads the external scraper by default, so the independently collected data is available but not what users see until you switch the website's fetch script, and doing that switch is a manual step in the rollout rather than an automatic one. The third is the XPI version range. Compatibility is determined by the manifest inside the XPI, so a plugin that ships an unusual manifest, or none, will have an incomplete range, and the historical release selectors for older Zotero versions still need human maintenance. The alternative to weigh is the upstream addons directory itself, which is the source this project reconciles against. Building on that gives you a simpler dependency, at the cost of the compatibility corrections and the local-only plugins this catalog adds.
Submitting a plugin, and what the project asks for
The contribution rules are specific, and they tell you what the project values. For a new plugin you include the repository URL, a brief description and a release or download link, and in a pull request you add an entry to src/plugins.ts in repository-name order with repo, tags, releases and discoverReleases set to true. An empty releases array enables discovery of the latest stable release. For an update to an existing entry you describe the correction, whether that is a repository transfer, a category, a download URL or a historical compatibility range, and you include supporting links. The README also explains why ordinary version releases do not need a manual edit: the collector checks the latest stable release, so only historical release selectors need upkeep for older Zotero versions. Reviewed submissions enter the local catalog after merging, and whether the plugin then appears in the store depends on publication builds and the website's configured data source. Submissions are accepted through an issue or a pull request, and there is a Chinese version of the README at README-zh.md.
Editorial conclusion
Adopt zotero-plugins if you are running a Zotero plugin directory or want the XPI compatibility ranges and download links catalogued for you, since the repository does the version detection and source reconciliation work that is tedious to do by hand. Do not adopt it as a plugin for Zotero itself, because it is a catalog and collector, not an add-on, and note that the repository description currently marks maintenance as suspended even though the README says submissions are open again. Before you build on it, read the collector rollout section to understand the difference between shadow and primary mode, and check the reconciliation report, which puts the local catalog at 337 repositories against 336 published plugins.
Frequently asked questions
What is the zotero-chinese zotero-plugins repository?
It maintains a local Zotero plugin catalog and independently collects repository metadata and XPI compatibility information. The published catalog is served at zotero-chinese.com/plugins, and the project is MIT licensed with TypeScript as the primary language.
How does the project determine which Zotero versions a plugin supports?
The README says XPI manifests determine compatible Zotero versions, listed as 6 to 11. Historical release selectors are combined with the newest stable release from the most recent release page, and those historical selectors still need manual maintenance for older Zotero versions.
What is the difference between shadow and primary collector mode?
The default shadow build runs the collector and compares its candidate data with the external scraper, while published plugins.json keeps using the external data during validation. Running CI manually with collector-mode: primary publishes independently collected data, and setting the repository variable COLLECTOR_MODE=primary retains that mode for scheduled builds.
How do I add a new plugin to the catalog?
You include the repository URL, a brief description and a release or download link, and in a pull request you add an entry to src/plugins.ts in repository-name order with repo, tags, releases and discoverReleases set to true. An empty releases array enables discovery of the latest stable release, and submissions go through an issue or a pull request.
How does the scheduled upstream source sync work?
The .github/workflows/sync-source.yml workflow runs daily at 05:45 Asia/Shanghai and supports manual dispatch. It merges the upstream source catalog and the latest published snapshot, then creates or updates a pull request on the automation/sync-syt2-sources branch, which has to be reviewed and merged to update the collector's sources. Pull requests are never merged automatically and upstream code is not executed.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zotero-chinese-zotero-plugins)Was this useful?