In keeping with a previous post I’d made a couple months ago explaining the oft-discussed rationale of why we do things the way we do with Jetpack, I’ll be doing it again today, on a different — but related — topic.
I may as well make a series of it.
This is the first of two posts (in theory, I’ll remember to write the second) explaining why Jetpack is a big plugin with many features, rather than many individual plugins. This post will be looking at the primary technical reason. The abundance of other reasons will be in the subsequent post. (So please don’t read this post and think it’s the only reason — it’s not)
tl;dr: Dependency management sucks.
Jetpack, as you may be aware, is structured as a bunch of modules. Many — but not all — require a connection to WordPress.com to function. This isn’t for vanity purposes, it’s because they actually leverage the WordPress.com server infrastructure to do things harder, better, faster, stronger than a $5/month shared host is capable of. To do that, they need to be able to communicate securely with WordPress.com, and WordPress.com must be able to communicate securely back to your site.
Some of the modules that require a connection are things such as Publicize (which uses the WordPress.com API keys to publicize to assorted third-party systems, rather than making users register various developer accounts and get their own API keys), Related Posts (which syncs some content up to the WordPress.com servers and indexes it on a large ElasticSearch index more efficiently and accurately than could be done in a MySQL database), Monitor (which pings your site every five minutes and emails you if it’s down), Comments (which passes data back and forth behind the scenes to enable secure third-party comment authentication) — you get the idea.
We could bundle the connection library with each individual plugin. However, we’d need to make sure it was namespaced correctly so each different plugin can use its own correctly versioned instance of the connection classes. Which would then mean a user could have well over a dozen copies and different versions of the same connection class active at a given time. Which will make things more difficult with respect to developing the plugins, as you can’t assume methods in one are necessarily in another. And when you make a change in the master class, you need to scan each repository to make sure you’re not breaking anything there, and keep changes synced to well over a dozen repositories. But I digress.
To avoid duplicate code, the modules that depend on talking back and forth with WordPress.com all use a common library that handles signing and verifying requests, API calls, and the like.
Because it’s all packaged in a single plugin, we can be sure that it’s all running the required version. If Publicize needs a change in the core connection library, we can be sure that the version of the connection library in Jetpack has those changes. If the core connection library needs to change structure, we can make sure that any modules that used the old methods are updated to run the new ones instead. Everything is maintained so that it’s running smoothly and works properly with each other.
Now, if Likes, Single Sign On, After the Deadline, Post by Email and others were their own plugins, and connected to a separate Jetpack Core plugin, versioning gets tricky. It could work, in theory, if every plugin is kept up to date, always and forever. But the instant that the user is using, say, an outdated version of Subscriptions with an outdated Jetpack Core (which work perfectly together), and then installs the up-to-date WP.me Shortlinks plugin, things could break because WP.me Shortlinks expects a more up-to-date Jetpack Core. So you go ahead and update Jetpack Core to current, but now Subscriptions — which used to work perfectly — now breaks because there was a method change in Jetpack Core, that is fixed in the up-to-date version of Subscriptions, but the user isn’t running the up-to-date version. Horrible UX.
Plus, if the user doesn’t have any Jetpack stuff, the installation flow for their first Jetpack Plugin that needs the core would be something like this:
- Install Stats.
- Activate Stats.
- Get error saying you need Jetpack Core for Stats to function.
- WTF is Jetpack Core? I just want Stats!
- Okay, install Jetpack Core.
- Activate Jetpack Core.
- Wait, what was I doing?
- Stats! Okay, right.
- Connect the Jetpack Core to WordPress.com.
- Drink Scotch in celebration.
Compare this to the status quo of:
- Install Jetpack.
- Activate Jetpack.
- Connect Jetpack to WordPress.com.
- Stats is already active (unless you’re Mark Jaquith, in which case you activate it in this step)
- Drink Scotch in celebration.
As I said, dependency management is hard, and there’s not really a good way to manage it in WordPress. There have been some very worthwhile attempts made, but none that can have a sufficiently solid user experience for an average user to compare with our current system and flow.
Any questions or suggestions about dependency management and Jetpack? Ask away!