Troy: The Private Plugin Railroad Hidden Inside WordPress
A monorepo that turns WordPress into a private distribution system, intercepts update checks, and keeps premium plugins off WordPress.org’s radar.
- Troy is not a plugin helper, it is a private control plane for WordPress distribution.
- The client hides Troy-managed plugins from WordPress.org and then merges private update data back into the normal dashboard.
- The MU-plugin daemon turns privacy into enforcement by blocking the public update path if the client disappears.
- Troy competes less with plugin install tools than with the assumption that WordPress.org must sit in the middle of plugin delivery.
WordPress still looks normal. That is the trick. Troy leaves the familiar update screen in place, then reroutes the data flow so participating plugins pull from a private server instead of WordPress.org.
That makes the project feel larger than a plugin. It is a distribution system, an enforcement layer, and a privacy policy bundled into one monorepo.
Four pieces, one private distribution system
Troy splits the job across four components. The Server hosts the private repository, the Client intercepts updates on the site, the Daemon keeps the client from being quietly removed, and the Installer bootstraps the whole setup.
The architecture matters because it changes the unit of control. Troy does not ask each plugin author to reinvent update logic. It gives them a private rail system, then makes the rail system look native to WordPress.
The Client intercepts WordPress before it speaks
The Client is where the sleight of hand happens. It hooks the HTTP layer, watches requests headed to api.wordpress.org, and removes Troy-managed plugins from those checks so WordPress.org never sees them.
Then it works in the other direction. When WordPress asks for update data, the Client queries registered Troy Servers, gathers private metadata, and merges the results back into the update transient so the dashboard behaves as usual.
add_filter('http_request_args', [$this, 'filter_request_args'], PHP_INT_MAX);
add_filter('pre_set_site_transient_update_plugins', [$this, 'filter_update_transient']);
The result is subtle but important. Users still get standard update UX, but the source of truth is private and controlled by the repo owner.
The daemon that refuses to be turned off
The MU-plugin daemon is the most forceful part of Troy. If the Client is deactivated or WordPress enters recovery mode, the daemon blocks WordPress.org API traffic until the private path is restored.
That is a strong opinion about software ownership. Troy treats update privacy like a security control, not a convenience setting.
Troy isn’t a replacement for WordPress.org—it’s an addition. Another option. A backup. A parallel path for developers who want independence.
Dependencies become installable, not manual
Troy also treats dependency delivery as a first-class workflow. Plugins can declare a Troy Dependency header, and the Client can install those dependencies in the background without sending the user on a scavenger hunt for ZIP files.
That changes the operational model. The old pattern is manual upload, fragile instructions, and support tickets. Troy pushes the work into the distribution layer, where it belongs if you want repeatable installs.
| Approach | Private repo | Update interception | Dependency support | Admin UI | Operational burden |
|---|---|---|---|---|---|
| Troy | Yes | Yes | Yes | Yes | Low after setup |
| plugin-update-checker | Possible, but embedded in each plugin | Yes, inside plugin code | Not native | No central repo UI | Medium to high |
| Manual ZIP upload | No | No | No | Only WordPress core | High |
This is where Troy stops feeling like a one-off update trick and starts feeling like package management for WordPress.
Why Troy feels like a counter-model to WordPress.org
The project is not trying to be neutral. It is built around ownership, privacy, and commercial independence. The repo is MIT licensed, and the author is explicit about wanting a parallel path for developers who do not want their distribution channel mediated by a central directory.
That stance shows up in the product choices. Troy can hide site-level metadata from WordPress.org, support private commercial plugins, and keep the distribution relationship between the author and the customer.
In other words, Troy is not just a technical workaround. It is an argument that plugin distribution should be owned, not borrowed.
What Troy is really competing with
Troy is most usefully compared with two familiar patterns: libraries like plugin-update-checker, and the old manual ZIP workflow. The library gives you update plumbing inside each plugin. The ZIP path gives you no infrastructure at all.
| System | What it is | Best for | What it lacks |
|---|---|---|---|
| Troy | A full private distribution system | Teams that want controlled plugin delivery | It adds operational complexity upfront |
| plugin-update-checker | A library embedded in a plugin | Single-plugin custom update flows | No centralized repo or enforcement layer |
| Manual upload | A human process | Occasional installs | No automation, no dependency management, no privacy control |
That is Troy’s real position in the market. It is not competing on whether a plugin can update. It is competing on who owns the route those updates take.





