Introduction to Troy

Troy is an open-source plugin suite that lets WordPress developers distribute their plugins independently—from their own servers, on their own terms.

How It Works

Troy has two main components:

Troy Client

For site owners who want to receive plugin updates from developers using Troy.

  • Install the plugin, activate it, done.
  • Updates appear in your normal WordPress dashboard—no extra steps.
  • Privacy-first: only essential data is shared, anonymized via rotating identifiers.

Troy Server

For plugin developers who want to host their own update repository.

  • Upload a ZIP file, connect your (public or private) GitHub repository, or auto-import releases from WordPress.org.
  • Share your Troy Server URL with users.
  • Updates flow through WordPress's native update system—users see them just like any other plugin update.

That's it. No complicated setup, no ongoing maintenance burden. Your server, your rules.

Why Troy Exists

WordPress is self-hosted software—but its plugin ecosystem runs through a single distribution point. Plugin developers have watched their work get blocked, hidden, or removed from WordPress.org—sometimes without warning, often without recourse. Centralized control over plugin distribution leaves developers vulnerable.

Your code is yours. You wrote it. Your users chose it. No directory should hold that relationship hostage.

Troy was built so you don't have to ask permission to distribute your own software.

The Philosophy

Troy is developed by Sybre Waaijer, creator of The SEO Framework. After contributing over 30,000 hours to the WordPress ecosystem—and experiencing firsthand what happens when a centralized directory severs the connection between a developer and their users—he built Troy on the principles that guide all his work:

  • Never release with bugs. Your users' sites are not testing facilities.
  • Respect every user. Whether free or paid, everyone deserves working software.
  • Prevent problems, don't just solve them. Good design eliminates the need for support.
  • Fair and honest. No dark patterns, no vendor lock-in.

Troy isn't about competing with WordPress.org—it's about having an alternative when you need one. For the full story behind why Troy exists, read the introductory blog post.

Why MIT Instead of GPLv2

WordPress uses the GPLv2 license, and that's fine for many projects. But GPLv2 is a copyleft license: it requires derivative works to also be GPLv2. This creates a form of license lock-in.

Troy uses the MIT license because:

  • Freedom without strings. Use Troy in any project—commercial, proprietary, or open source.
  • No viral licensing. Your plugins don't inherit license requirements from Troy.
  • Simpler compliance. MIT is short, clear, and widely understood.

We believe true software freedom means freedom to choose—including your license.

Architecture

Troy's design centers on two principles: use WordPress's existing infrastructure where possible, and never expose more data than necessary. Read our privacy policy for the full details.

Plugin Opt-In

A plugin author opts into Troy by adding a Troy header to their plugin's main PHP file, pointing to the developer's Troy Server URL:

/**
 * Plugin Name: My Plugin
 * Troy:        repo.example.org
 */

Without this header, Troy ignores the plugin entirely. Nothing changes for plugins that don't opt in.

Update Flow

When WordPress checks for plugin updates, Troy Client intercepts the process:

  1. Discovery. Troy Client scans all installed plugins for the Troy header. Plugins are grouped by their Troy Server URL.
  2. Server query. For each Troy Server, the Client sends a single POST request to the server's update endpoint. The request includes active and inactive plugin versions, PHP and WordPress versions, and the preferred release channel—but only for plugins hosted on that specific server. No cross-server data leaks.
  3. Merge. The server responds with available updates. Troy Client merges these into WordPress's native update_plugins transient—the same data structure WordPress itself uses. Updates appear in the dashboard like any other plugin update.

WordPress.org Isolation

Troy Client doesn't just add its own updates—it actively removes Troy-header plugins from WordPress.org API requests. When WordPress sends its update check to api.wordpress.org, Troy Client strips:

  • All plugins with a Troy header from the plugin list
  • The Troy header key from all remaining plugins (WordPress registers it on every plugin file—stripping it prevents WordPress.org from seeing the key exists)
  • Text domains of Troy:-header plugins from translation requests

WordPress.org never sees that Troy plugins exist on the site.

Privacy

Troy Client identifies itself to Troy Servers using a weekly-rotating anonymous identifier—a random 256-bit value prefixed with a time epoch. No site URL, no admin email, no personally identifiable information is transmitted. The default WordPress user agent (which includes the site URL) is replaced with a generic Troy Client identifier for all Troy Server requests.

Each Troy Server only receives data about plugins hosted on that specific server. A developer running Troy Server cannot see what other Troy Servers a site connects to.

Server-Side

Troy Server exposes a REST API that serves plugin updates, information, downloads, version tags, and usage statistics. Developers can add plugins through three methods:

  • ZIP upload. Upload a plugin ZIP directly through the admin interface. Troy Server extracts it, validates the plugin headers, repackages it with a consistent directory structure, and stores it with a SHA-256 checksum.
  • GitHub integration. Connect a GitHub repository (public or private). Troy Server polls for new tags every 30 minutes and automatically imports matching releases.
  • WordPress.org sync. Connect by plugin slug. Troy Server monitors WordPress.org for new versions and auto-imports them—useful for mirroring your own plugin as a fallback distribution channel.

Each integration supports configurable auto-processing: import all releases, only stable tags, only betas, or manual review.

What Troy Is Not

Troy is designed as a sideloading system, not a replacement for WordPress infrastructure:

  • Not a replacement for WordPress.org. Troy doesn't replace the WordPress.org update system—it works alongside it for plugins that opt in.
  • Not mutually exclusive. You can host the same plugin on both WordPress.org and Troy Server. Troy headers are inert metadata that WordPress.org ignores.
  • Not a blocking tool. Troy doesn't prevent other plugins from communicating with their own servers or WordPress.org.
  • Not a WordPress core updater. Troy handles plugins only. Core updates still come from WordPress.org.
  • Not a drop-in API replacement. Troy uses its own protocol; it's not compatible with WordPress.org's update API format.
  • Not a protest tool. It's practical infrastructure for developers who need independence.

What Troy Does

  • Sideloads plugin updates from distributed, developer-hosted Troy Servers.
  • Opt-in only. Plugin developers join by adding the Troy header. Troy Client ignores all other plugins.
  • Coexists with WordPress.org. The same plugin file works on both platforms—Troy Server can even auto-import releases from WordPress.org.
  • Privacy-preserving. Troy Client filters Troy plugins out of WordPress.org requests entirely. WordPress.org never sees them.

Getting Started

Ready to try it?

Community

Troy is community-driven and open source. Found a bug? Have a feature request? Want to contribute?