How Are MU-Plugins Loaded?

MU-Plugins, or Must-Use Plugins, are plugins that are loaded automatically by WordPress before regular plugins are loaded in. They are crucial in providing functionality that can never be deactivated, will always run, and will run everywhere, including across all sites on a Multisite network.

But how are MU-Plugins loaded, and why are they loaded first? In this tutorial, I’ll go over each point, lay out the developer tradeoffs, and explain why you should add MU-Plugins to your toolkit.

What are MU-Plugins?

To summarize my article on how to create MU-Plugins, MU-Plugins:

  • Live inside the wp-content/mu-plugins folder as PHP files.
  • They are executed automatically, in alphabetical order.
  • They cannot be deactivated.
  • They cannot be edited or updated in the admin.

What are MU-Plugins Used For?

MU-Plugins are helpful in housing critical site functionality that cannot be deactivated. Examples could be:

  • Registering Custom Post Types and Taxonomies.
  • Enabling a site-wide feature, such as a font filter for the theme/block editor.
  • Site-wide tweaks that shouldn’t be deactivated, like removing the customizer or the admin toolbar.
  • Critical features that shouldn’t be deactivated, such as security rules.
  • Permalink rewrite rules that should rarely change.
  • Hook into other plugins early, modifying their behavior.

In general, if you want a piece of code that runs early and everywhere, MU-Plugins are your solution.

How MU-Plugins Are Loaded

Friend Remkus de Vries posted a very detailed article on how WordPress is loaded. Rather than regurgitating word-for-word, please check out his article. I’ve included a diagram below of the loading order as mentioned in the article.

Diagram of WP Loading, Showing the WordPress Loading Order
Diagram of WP Loading, Showing the WordPress Loading Order

As shown in the diagram above and mentioned in the wp-loading article, MU-Plugins are loaded just after Multisite is initialized, default filters have been set, and the database has been initialized.

WordPress literally does a folder scan and does a foreach loop to include all of the mu-plugin files.

PHP – wp-settings.php
// Load must-use plugins.
foreach ( wp_get_mu_plugins() as $mu_plugin ) {
	$_wp_plugin_file = $mu_plugin;
	include_once $mu_plugin;
	$mu_plugin = $_wp_plugin_file; // Avoid stomping of the $mu_plugin variable in a plugin.

	/**
	 * Fires once a single must-use plugin has loaded.
	 *
	 * @since 5.1.0
	 *
	 * @param string $mu_plugin Full path to the plugin's main file.
	 */
	do_action( 'mu_plugin_loaded', $mu_plugin );
}
unset( $mu_plugin, $_wp_plugin_file );
MU-Plugins Loaded

Function wp_get_mu_plugins is called, which retrieves all of the available MU-Plugins.

wp_get_mu_plugins function
wp_get_mu_plugins function

This scans the folder for any PHP files, even those hidden with dot notation, and includes them.

PHP
function wp_get_mu_plugins() {
	$mu_plugins = array();

	if ( ! is_dir( WPMU_PLUGIN_DIR ) ) {
		return $mu_plugins;
	}

	$dh = opendir( WPMU_PLUGIN_DIR );
	if ( ! $dh ) {
		return $mu_plugins;
	}

	while ( ( $plugin = readdir( $dh ) ) !== false ) {
		if ( str_ends_with( $plugin, '.php' ) ) {
			$mu_plugins[] = WPMU_PLUGIN_DIR . '/' . $plugin;
		}
	}

	closedir( $dh );

	sort( $mu_plugins );

	return $mu_plugins;
}

After all MU-Plugins have loaded, the action mu_plugin_loaded is fired, letting others know programmatically that a plugin has been loaded.

Finally, once all MU-Plugins are loaded in, the action mu_plugins_loaded is fired.

PHP
<?php
/**
 * Plugin Name: Do MU-Plugin Stuff (MU)
 * Description: Does MU-Plugin stuff.
 */

add_action(
	'muplugins_loaded',
	function () {
		// Do things before other regular plugins.
	},
	10
);

Since MU-Plugins are loaded before regular plugins, you control plugin behavior and can perform other tasks that may need to be completed before regular plugins are loaded.

Why Are MU-Plugins Loaded First, Before Regular Plugins?

This is to strike a balance between plugin execution and general code execution. For example, a themer might use functions.php to run custom code because that’s the earliest a theme author can do it. However, a plugin author can run much earlier, even modifying the theme that the user sees, bypassing functions.php.

An MU-Plugin loads before other plugins so that it can perform additional checks much earlier than a plugin or theme.

The ability to have always-on code, running at the earliest possible iteration, is what makes MU-Plugins a great tool.

Conclusion

In this tutorial, I went over how MU-Plugins are loaded, referenced an in-depth article on WordPress loading, and demonstrated some use cases for when you would use them.

Please check out my other article on creating MU-Plugins for more information. As always, feel free to leave a comment, and I’ll respond to your question.

Like the tutorial you just read? There's more like it.

There's more where that came from. Enter your email and I'll send you more like it.

This field is for validation purposes and should be left unchanged.

Ask a Question or Leave Feedback

Your email address will not be published. Required fields are marked *