Every WordPress guide tells you to "add this to your functions.php" — but that's fragile advice. Theme updates can overwrite your changes, child theme setups add complexity, and one syntax error in functions.php crashes your entire site.
There's a better way: mu-plugins (must-use plugins).
What Are mu-plugins?
mu-plugins (must-use plugins) are PHP files placed in wp-content/mu-plugins/. WordPress loads them automatically on every request — no activation needed, no accidental deactivation possible.
| Feature | functions.php | Regular Plugin | mu-plugin |
|---|---|---|---|
| Survives theme update | No | Yes | Yes |
| Can be accidentally deactivated | Theme switch = gone | Yes | No |
| Loads automatically | With theme | After activation | Always |
| Visible in admin | No | Plugins page | Must-Use tab |
| One syntax error = | Site crash | Plugin crash | Site crash* |
* Same risk as functions.php, but mu-plugins are isolated files — easier to fix via FTP because you can delete just the problematic file.
How to Set It Up
Safe Practice: Before making any technical changes, ensure you have a full backup of your site (files and database) via your hosting control panel or a dedicated plugin like UpdraftPlus.
Step 1: Create the Directory
Connect to your site via FTP, File Manager, or SSH and navigate to wp-content/.
Create a folder called mu-plugins if it doesn't already exist:
- File Manager / FTP: Right-click → New Folder → name it
mu-plugins - SSH:
mkdir mu-plugins
Step 2: Create Your First mu-plugin
Create a new PHP file inside mu-plugins/. Name it descriptively — for example, site-tweaks.php:
<?php
/**
* Plugin Name: Dravasite – Site Tweaks
* Description: Custom performance and security tweaks.
* Version: 1.0.0
*/
// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
exit;
}The Plugin Name header is important — it makes your mu-plugin show up properly under Plugins → Must-Use in the admin panel.
Step 3: Add Your Code Snippets
Add each snippet below the header. Here's an example combining several common tweaks:
<?php
/**
* Plugin Name: Dravasite – Site Tweaks
* Description: Custom performance and security tweaks.
* Version: 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// ── Remove emoji script (browsers handle emoji natively) ──
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
// ── Slow down Heartbeat API (default: 15s → 120s) ──
add_filter( 'heartbeat_settings', function ( $settings ) {
$settings['interval'] = 120;
return $settings;
} );
// ── Disable XML-RPC (legacy remote access) ──
add_filter( 'xmlrpc_enabled', '__return_false' );One File or Many?
One file is simpler for small sites. Name it something like site-tweaks.php.
Separate files are better when you want to quickly enable/disable individual tweaks by renaming or deleting a single file:
mu-plugins/
├── disable-emoji.php
├── heartbeat-control.php
├── disable-xmlrpc.php
└── dequeue-duplicate-jquery.phpBoth approaches work. Choose whatever is easier for you to manage.
Template for Single-Purpose mu-plugins
Use this template for each standalone tweak:
<?php
/**
* Plugin Name: Dravasite – Disable Emoji Script
* Description: Removes the WordPress emoji detection script.
* Browsers handle emoji natively since 2015.
* Version: 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Remove emoji JavaScript from <head>
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
// Remove emoji CSS from stylesheets
remove_action( 'wp_print_styles', 'print_emoji_styles' );Notice how each line has a comment explaining what it does and why. Future-you (or the next developer) will thank you.
How to Verify
After uploading your mu-plugin:
- Go to Plugins in your WordPress admin
- Click the "Must-Use" tab at the top
- Your plugin should appear there with the name and description from the header
If you don't see the Must-Use tab, it means the mu-plugins directory doesn't exist or has no valid PHP files.
Common Mistakes
- Missing the opening
<?phptag — every mu-plugin file must start with it - Syntax errors — test your snippet on a staging site first. A broken mu-plugin crashes the site just like a broken functions.php
- Subdirectories — WordPress only loads PHP files directly inside
mu-plugins/. Files in subfolders are ignored by default - Missing
ABSPATHcheck — always include theif ( ! defined( 'ABSPATH' ) ) exit;guard to prevent direct file access
Why Not functions.php?
| Scenario | functions.php | mu-plugin |
|---|---|---|
| You switch themes | Code is lost | Code stays |
| Theme updates | Risk of overwrite (without child theme) | Unaffected |
| You want to quickly disable one tweak | Edit file, find the code, comment it out | Delete one file |
| Multiple developers | Everyone edits one file = merge conflicts | Separate files = no conflicts |
What to Watch For
- mu-plugins load before regular plugins and before the theme. This means you can't use theme functions or plugin APIs in mu-plugins unless you hook into
plugins_loadedor later. - mu-plugins don't have an "update" mechanism — you manage them manually (which is fine for small code snippets).
- If you're on managed hosting (Kinsta, WP Engine), check if they allow mu-plugins. Most do, but some restrict the directory.