Yet Another Plugin Dependencies Discussion, Two Proposals This Time

It has been over nine years since the late Alex Mills opened a ticket on WordPress Trac titled Plugin Dependencies (Yet Another Plugin Dependencies Ticket). It is not the oldest of similar feature requests, but it is still open. Most predecessors were closed with the “wontfix” label, which is usually the final nail in the coffin of good and bad ideas alike.

The goal of the ticket is to create a system that allows one plugin to require one or more others to operate. Dependencies are nothing new in the programming world. Composer, the standard PHP package manager, is two weeks shy of turning 10 years old. On the JavaScript end, npm has been around for 12 years, and WordPress has heavily embraced it for core code.

However, those are developer tools. WordPress was built for users, and resolving plugin dependencies would need to happen from within the user interface.

Mills wrote in the ticket:

It’s been a few years since we looked at plugin dependencies, and this still seems to be a feature people really, really want, especially for shared functionality that isn’t a plugin in itself. For example, a PHP library that isn’t popular enough to be in core but is popular enough to be bundled in multiple plugins.

That statement is perhaps even more relevant today. In the past decade, many plugins have grown their own ecosystems of add-on plugins. The responsibility of making sure dependencies are installed has often fallen on the shoulders of end-users. Developers have come up with in-house solutions to ease that burden, and the TGM Plugin Activation script has become the de facto standard.

Relying on dependencies is almost a given in any plugin project, at least playing a part in the average build tools setup. It is probably safe to say that more WordPress plugin developers are comfortable coding in an environment that requires third-party code today than they would have been in WordPress’s formative years.

For a platform that has been working hard to modernize itself, resolving plugin dependencies is like traveling in a rocket ship to the Wild West.

The idea is not without precedent in the WordPress world. While it is a less complex case, WordPress automatically downloads and installs the parent when installing a child theme from the directory.

Many arguments for a plugin dependency system fall under the add-on scenario. The most obvious use case is WooCommerce and the dozens upon dozens of extensions written for it.

However, the other scenario that can reach deeper into how developers build on top of WordPress is the inclusion of frameworks and libraries. Right now, plugin authors must bundle third-party code within their projects and make sure it does not get loaded if already bundled within an entirely separate plugin.

Code reuse is one of the cornerstones of programming. The WordPress plugin directory disallows new frameworks and similar libraries. However, we could revisit this decision with a dependency system in place. It could open the possibility of making libraries available as standalone extensions that any other plugin could use.

For transparency, I have at least a dozen projects that fit under this category, packages sitting around that others could use. So, I at least have some skin in the game, and I am sure many others are in the same boat.

There are two pull requests on the WordPress GitHub repository for a plugin dependency system. There is also a Google Docs file that outlines both proposals in detail.

Each asks developers to define dependencies via a plugin header. The following is an example that would require WooCommerce and Gutenberg:

<?php
/**
 * Plugin Name: Sample
 * Requires Plugins: woocommerce, gutenberg
 */

Both of the approaches are similar. From the user viewpoint, they would:

  • Show an admin notice that there are dependencies to install.
  • Disallow deletion or deactivation of plugins without deleting or deactivating their required plugins.
  • Output a message in the plugin card on the manage plugins screen.

The first implementation is by Ari Stathopoulos. It creates an “activation queue” that would only activate a plugin once users have activated the required plugins. It also allows users to cancel activation requests.

Manage plugins screen in WordPress that shows admin notices to install dependent plugins and similar messaging in the plugin card.
Notices to activate dependencies.

Andy Fragen’s solution creates a new “Dependencies” tab on the plugin management screen. This approach would automatically deactivate any plugin with unmet dependencies and inform the user via an admin notice.

He has also released the Plugin Dependencies Tab project separately on GitHub.

Plugin dependencies screen in WordPress for activating and installing required plugins.
Plugin dependencies tab.

There are still some practical concerns with both. Namely, what happens when there is a conflict between supported versions? The current proposals leave it up to the plugins to not break anything on the user’s end.

That may be the least confidence-inspiring piece of all of this. However, it is likely the most practical route. Plus, WordPress does not solve version conflicts in its current Wild West system.

A dependency solution could also be an opportunity for more code modernization. Seeing more developers embracing features like interfaces (contracts) would be welcome. Coding with dependents in mind means thinking through architectural problems differently than when any given project was a standalone plugin.

9 responses to “Yet Another Plugin Dependencies Discussion, Two Proposals This Time”

  1. Just a comment regarding this:

    There are still some practical concerns with both. Namely, what happens when there is a conflict between supported versions? The current proposals leave it up to the plugins to not break anything on the user’s end.

    To provide some context:
    Checking for a minimum version is simple enough, and it was initially part of the implementation. However, checking for a maximum version was deemed bad practice because in WordPress all plugins should ALWAYS be kept up to date. Introducing a version-check in dependencies was therefore deemed unnecessary as it would promote bad practices, and the implementation was removed.

    Can you imagine for example plugin A requiring plugin B v2.0.x, and not letting users update to v2.1.x? It would be a nightmare scenario for security!

    With the above in mind, it was simpler and more efficient to let plugin developers handle their own backward-compatibility, and not force any sites to use older versions of plugins because of dependencies that someone forgot to update on their plugin :)

    • Thanks for expanding on the thought process there, Ari. I agree that this makes the most sense in a WordPress context, especially because we have no community standards on backporting security fixes to older versions. It actually makes everything simpler (just keep things updated).

  2. This would be great. As also mentioned in the article we are currently using TGM Plugin Activation as a solution to this. I like this solution because it also empowers developers to include Git repositories or premium plugins. I don’t see that kind of inclusion happening in a WordPress solution, or at least not initially.

  3. This feature is very important. It would definitely solve the serious problem that occurs when you selectively disable plugins on specific pages that would depend on other plugins.

    WordPress gives you the possibility to filter the core option “active_plugins”. This means that if in a plugin you check the presence of a third plugin by looking at that option, and in a mu-plugin that option is filtered, you may think that plugin is active, but it isn’t.

    Some plugins use functions defined in other plugins without checking first the existence of that functions, but only checking the core option “active_plugins”. I have seen a lot of these kinds of plugins. When you have this kind of plugin and you selectively disable plugins on specific pages, the risk you have a fatal error is very high. Plugin dependencies managed by the core would avoid this kind of issue.
    I really hope this feature is implemented in the core. I also ask: why not? What’s the downside? The supported versions are another topic.
    If plugin B needs plugin A, it will always need it. I agree that this is a necessary but not sufficient condition, but let’s first be sure the necessary condition is satisfied, and then the version compatibilities can be managed by the code of the plugins. The necessary condition that plugin A must be active should be managed by the core.

    I don’t understand why after so many years this feature is still not implemented.

    • Plugins requiring dependencies still should behave properly and degrade gracefully if the dependency is not active.

      Thanks for the write up Justin. There is much more information about the PRs in the actual PR as well as in the original ticket. I encourage anyone interested to dig deeper. 😉

      There will be a Make post for further discussion coming soon. Ari and I have provided our interpretations. Think about what the best design and discovery need to be discussed to arrive at a solution.

  4. Ari and Andy are great developers who spent a lot of time on this (you can check their work on Github). Really respect them on that.

    If this can be resolved either way, it will push WP forward a lot and embrace developers to build better apps for WP. Sharing codebase, remove duplication, using up-to-date plugins are some of the benefits.

  5. I don’t think the issue of versioning should be a concern.

    The WordPress ecosystem largely doesn’t support older versions and has an expectation of things being kept current and up to date.

    It’s nice to see this issue hasn’t been forgotten. I remember having many discussions about this a long time ago, and just gave up hope on it ever being supported in core.

    The proposals here look pretty good to me.

    There are also issues with plugins which don’t have “dependencies” per se, but which will gain extra features if other plugins are loaded. I don’t think these proposals handle that scenario, but perhaps it’s not a priority at this stage either. It’s an important thing to factor into the architecture though, as specific support for that concept may something considered suitable for later perhaps.

Newsletter

Subscribe Via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

%d bloggers like this: