The mu-plugins directory can often become full of various files that have basically been dropped in to solve a particular problem for the particular WordPress installation.

In my experience, these are often useful plugins but they aren’t structured like more standard plugins. That is, mu-plugins often look like a bunch of files dropped in the directory that don’t make a lot of sense unless you read the files. Further, an mu-plugin is often a single file that’s monolithic in nature.

Given the nature of mu-plugins, there’s a case to be made they shouldn’t need to be structured like that. Of course, if you’re building some advanced functionality that is considered must-use, then I think it’s worth building it in such a way that follows modern standards and still works within the mu-plugins structure.

What options are there, though?


I’m sure there are many solutions for how to do this but the way that I’ve found to be cleanest while also allowing me to build plugins in the way I typically do is to maintain a bootstrap file in the mu-plugins directory that references the actual plugin which resides in its own subdirectory.

For example, let’s say I’m building a plugin called acme-solution and the basic file structure looks like something like this:

To drop this into the mu-plugins directory, it’s far too many files as it makes it difficult to maintain along with the rest of the plugins that are present (not to mention the work that may be required when working with a CI/CD app).

So then, I’ll create a bootstrap that looks like this

This obviously is named the same as the acme-solution subdirectory to keep cohesion as high as possible. Then the plugin that resides in acme-solution is structure the same as if it were a standard alone plugin.

And, for what it’s worth, the GitHub repository is structure exactly as you see here. That is:

  • CHANGELOG.md
  • README.md
  • LICENSE
  • composer.json
  • composer.lock
  • src/
  • vendor/

Are included in the repository as well.


Note

  • The vendor directory usually only includes the autoloader. I don’t recommend checking all of the dependencies into the repository unless there’s a good reason to do so.
  • Props to Benjamin Rojas for working with me on coming up with something that’s applicable across a variety of types of mu-plugins.