I’ve released Cross Post for Dev.to, a WordPress plugin that mirrors a post to Dev.to the moment you publish it on your own site. The plugin itself is simple: one hook, one API call, one published mirror. The interesting part of this release isn’t the feature. It’s what had to be true for a zero-dependency plugin to stay trustworthy over time without me babysitting it.
The problem
Most small WordPress plugins rot over time. They’re built against whatever WordPress version happens to be current, they lean on a third-party library or two to save time, and neither the plugin nor the library gets revisited until something breaks. Usually a major WordPress release, sometimes a PHP version bump. At that point the maintainer generally abandons the project and so many of these lesser used plugins become useless for users.
Cross-Post for Dev.to needed to cross-post reliably from WordPress to Dev.to without letting that happen so easily. No bundled third-party SDKs, no external service sitting between the plugin and the Dev.to API, no dependency that could go unmaintained while the plugin using it kept shipping.
Why zero-dependency isn’t the whole answer
Removing dependencies fixes one kind of rot but not the other. A plugin with no third-party packages can still quietly break against a new WordPress release; deprecated hooks, changed REST behaviour, PHP version drift. Zero dependencies means less that can fail underneath you; it says nothing about whether the plugin still works today. Those are two different guarantees, and conflating them is how “lightweight” plugins end up just as unmaintained as heavy ones, only with fewer visible warning signs.
So the actual problem wasn’t “avoid dependencies.” It was “know, continuously and automatically, whether this plugin still works”. Which is a validation problem, not a packaging problem.
The validation loop
Two layers of the same idea, one local and one continuous.
Locally, a pre-push hook runs before any commit leaves my machine: PHP linting, PHPCS against the WordPress coding standards, PHPStan for static analysis, then the unit and integration suites. If any of it fails, the push is blocked. This isn’t about catching typos, it’s about making sure a mistake never gets far enough to become someone else’s problem. The cost of finding a broken assumption is lowest the moment it’s introduced; a pre-push hook enforces that you pay it there, not after it is merged and breaking the main branch.
In CI, GitHub Actions runs the same checks against a matrix of PHP and WordPress versions on every push and on a schedule, independent of whether I’ve touched the code recently. That schedule matters more than it looks. WordPress core changes without waiting for plugin authors to notice, and a plugin that hasn’t been touched in eight months can silently stop being compatible with a WordPress release that shipped in month six. Scheduled CI turns “will this still work when someone installs it next week” from a question I’d have to remember to ask into one the pipeline answers on its own.
The local hook and the CI pipeline check the same things for a reason: local checks exist to keep bad changes from leaving my machine; CI exists to keep bad environments; a new WordPress version or a new PHP version, from silently invalidating changes that were fine when they were written. Neither one substitutes for the other.
What this actually enables
The real capability this buys isn’t “fewer bugs,” though that’s a side effect. It’s new WordPress or PHP versions stop being a maintenance crisis. Scheduled CI runs the test suite against a matrix of PHP and WordPress versions automatically. When WordPress 6.8 ships or PHP 8.4 goes stable, the pipeline runs the suite the same day. If it passes, great, the plugin is already known to be compatible. If it fails, I see the failure immediately and can fix it or publish a patch before a user even tries to upgrade.
That’s continuous validation without continuous attention: a plugin only stays trustworthy when someone is actively confirming it still works, and for most maintainers that someone is a person checking manually, usually late. This pipeline makes it an automated process, checking constantly, against the exact environments users will upgrade into, on a schedule that doesn’t depend on my memory or available time.
The end goal is pragmatic: new WordPress versions and PHP versions don’t impact this plugin in 99% of cases because the pipeline catches them and pushes a new release confirming that. In the remaining 1% of cases where there is a problem I’m notified about, I manually fix and publish a new release. That happens whether I’ve thought about the plugin that week or not.
That’s the same shift documentation-driven AI development is built on, and it’s worth naming directly: AI development is a documentation problem, not a prompting problem makes the case that AI coding tools don’t fail because of weak prompts. They fail because the surrounding context (docs, constraints, expected behaviour) isn’t captured anywhere machine-readable. The plugin’s CI pipeline is that same principle applied to compatibility instead of context: don’t rely on someone remembering to check. Encode the check so it runs whether they remember or not.
The code and pipeline are open: github.com/MChambers1992/cross-post-devto. The plugin itself is on WordPress.org: wordpress.org/plugins/cross-post-for-dev-to.
Also published on Medium.
