20 WordPress Plugins You Can Replace With a Few Lines of PHP
47 plugins on a client site, 23 needing updates. Here are 20 you can delete today and replace with a few lines of PHP that do the exact same thing.
I logged into a client's WordPress site last week. A site I built four years ago. 47 plugins installed. 23 needing updates. Three of them from developers who haven't pushed an update since 2024.
This is the reality of WordPress maintenance when you've moved on but your clients haven't. Every login is a minefield of update notifications, compatibility warnings, and that nagging feeling that one wrong click will break everything.
Here's the thing: at least 20 of those 47 plugins could be replaced with a few lines of PHP. Same functionality. Zero update anxiety.
Why Fewer Plugins Actually Matters
This isn't just about being tidy. There are real consequences to running a bloated plugin stack.
Performance: Every plugin adds HTTP requests, database queries, and CSS/JS files to your pages. Replacing 10 single-purpose plugins with code snippets can shave 150-300ms off your load time. That's not nothing.
Security: This is the big one. 91% of all WordPress vulnerabilities come from plugins. In 2025 alone, 11,334 new vulnerabilities were recorded, a 42% increase year-on-year. The median time from a vulnerability being disclosed to mass exploitation? Five hours. Every plugin you don't need is an attack surface you don't have.
Maintenance: Plugins get abandoned. Updates break things. Compatibility issues cascade. The fewer moving parts, the fewer things that can go wrong when you're maintaining WordPress security across multiple client sites.
Where to Put These Snippets
Before we get to the code, a quick note on where to put it.
Option 1: Child theme's functions.php. Fine for theme-specific stuff. Gets overwritten if you switch themes.
Option 2: mu-plugins folder. Create a PHP file in wp-content/mu-plugins/. Always active, can't be deactivated from the dashboard, persists across theme changes. This is my preference for site-wide functionality.
Option 3: Code snippet plugin (WPCode, Code Snippets). Gives you a GUI, categories, and a safe mode that catches fatal errors. Slightly ironic to install a plugin to avoid plugins, but it's genuinely useful if you're not comfortable with FTP.
Never edit the parent theme's functions.php directly. It'll get overwritten on the next theme update.
Security Snippets: Lock It Down
1. Disable XML-RPC
Replaces: Disable XML-RPC plugin (100k+ installs)
XML-RPC is an old remote access protocol that most sites don't need. It's a common brute force attack vector.
add_filter('xmlrpc_enabled', '__return_false');
One line. Done.
2. Hide WordPress Version Number
Replaces: Meta Generator and Version Info Remover plugin
Why broadcast which version you're running to anyone scanning for vulnerabilities?
remove_action('wp_head', 'wp_generator');
3. Disable File Editing in Dashboard
Replaces: Part of Sucuri, Wordfence security features
If someone gets admin access, you don't want them editing theme files from the browser. Add this to wp-config.php:
define('DISALLOW_FILE_EDIT', true);
4. Restrict REST API to Logged-In Users
Replaces: Disable REST API plugin (30k+ installs)
The REST API exposes data like usernames to anyone who asks. Lock it down for unauthenticated users:
add_filter('rest_authentication_errors', function($result) {
if (!is_user_logged_in()) {
return new WP_Error('rest_not_logged_in', 'API access restricted.', array('status' => 401));
}
return $result;
});
5. Disable Self-Pingbacks
Replaces: No Self Pings plugin
WordPress pings itself when you link to your own posts. Nobody needs that.
add_action('pre_ping', function(&$links) {
$home = get_option('home');
foreach ($links as $l => $link) {
if (strpos($link, $home) === 0) unset($links[$l]);
}
});
Performance Snippets: Speed It Up
6. Disable WordPress Emoji Script
Replaces: Disable Emojis plugin (50k+ installs)
WordPress loads an emoji detection script on every single page. Your server already handles emojis natively. This is dead weight.
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');
7. Remove jQuery Migrate
Replaces: Remove jQuery Migrate plugin (20k+ installs)
jQuery Migrate is a compatibility layer for old jQuery code. If your plugins and theme are up to date, you don't need it.
add_action('wp_default_scripts', function($scripts) {
if (!is_admin() && isset($scripts->registered['jquery'])) {
$scripts->registered['jquery']->deps = array_diff(
$scripts->registered['jquery']->deps, ['jquery-migrate']
);
}
});
8. Remove Query Strings from Static Resources
Replaces: Remove Query Strings From Static Resources plugin (20k+ installs)
Query strings on CSS and JS files can prevent proper caching.
add_filter('script_loader_src', function($src) {
return remove_query_arg('ver', $src);
});
add_filter('style_loader_src', function($src) {
return remove_query_arg('ver', $src);
});
9. Limit Post Revisions
Replaces: WP Revisions Control plugin
WordPress saves unlimited revisions by default, bloating your database. Add this to wp-config.php:
define('WP_POST_REVISIONS', 3);
10. Disable RSS Feeds
Replaces: Disable Feeds plugin
If nobody subscribes to your RSS feed (and let's be honest, on most business sites, nobody does):
add_action('do_feed', function() { wp_die('No feed available.'); }, 1);
add_action('do_feed_rdf', function() { wp_die('No feed available.'); }, 1);
add_action('do_feed_rss', function() { wp_die('No feed available.'); }, 1);
add_action('do_feed_rss2', function() { wp_die('No feed available.'); }, 1);
add_action('do_feed_atom', function() { wp_die('No feed available.'); }, 1);
Cleanup Snippets: Cut the Bloat
11. Disable Comments Entirely
Replaces: Disable Comments plugin (1M+ installs)
One million people installed a plugin for this. Here's the code:
add_action('admin_init', function() {
$post_types = get_post_types();
foreach ($post_types as $post_type) {
if (post_type_supports($post_type, 'comments')) {
remove_post_type_support($post_type, 'comments');
remove_post_type_support($post_type, 'trackbacks');
}
}
});
add_filter('comments_open', '__return_false', 20, 2);
add_filter('pings_open', '__return_false', 20, 2);
add_filter('comments_array', '__return_empty_array', 10, 2);
More than one line, sure. But it replaces a plugin with over a million active installations.
12. Remove Shortlink from Header
Replaces: Part of various cleanup plugins
remove_action('wp_head', 'wp_shortlink_wp_head');
13. Disable WordPress Search
Replaces: Disable Search plugin
For brochure sites that don't need search functionality:
add_action('parse_query', function($query) {
if (!is_admin() && $query->is_search) {
$query->is_search = false;
$query->query_vars['s'] = false;
$query->query['s'] = false;
$query->is_404 = true;
}
});
14. Remove RSD Link and WLW Manifest
Replaces: Part of header cleanup plugins
Relics from the blogging era. Nobody needs Really Simple Discovery or Windows Live Writer manifest links in 2026.
remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wlwmanifest_link');
15. Disable Auto-Updates
Replaces: Easy Updates Manager plugin
When you want full manual control over what updates and when:
add_filter('automatic_updater_disabled', '__return_true');
Customization Snippets: Make It Yours
16. Custom Excerpt Length
Replaces: Advanced Excerpt plugin
add_filter('excerpt_length', function() { return 25; }, 999);
Change 25 to whatever word count you need.
17. Add SVG Upload Support
Replaces: SVG Support plugin (800k+ installs)
add_filter('upload_mimes', function($mimes) {
$mimes['svg'] = 'image/svg+xml';
return $mimes;
});
Fair warning: this doesn't sanitize the SVG. For production sites handling user uploads, the Safe SVG plugin is still the safer choice because it strips malicious code from SVG files.
18. Disable Gutenberg Block Editor
Replaces: Classic Editor plugin (5M+ installs)
Five million installs. One line of PHP.
add_filter('use_block_editor_for_post', '__return_false');
19. Custom Login Logo
Replaces: Custom Login Logo plugin
add_action('login_enqueue_scripts', function() {
echo '<style>.login h1 a { background-image: url(' . get_stylesheet_directory_uri() . '/logo.png) !important; }</style>';
});
Drop your logo file in the theme directory, done.
20. Change "Howdy" in Admin Bar
Replaces: Replace Howdy plugin
Yes, there's a plugin for this. Yes, someone installed it.
add_filter('admin_bar_menu', function($wp_admin_bar) {
$my_account = $wp_admin_bar->get_node('my-account');
$newtext = str_replace('Howdy,', 'Welcome,', $my_account->title);
$wp_admin_bar->add_node(array('id' => 'my-account', 'title' => $newtext));
}, 25);
When Plugins Are Still the Right Call
I'm not telling you to go plugin-free. That would be stupid.
WooCommerce? You need that plugin. A solid caching solution like FlyingPress? Absolutely, caching logic is too complex for a snippet. Contact forms, SEO suites, backup solutions: those are real, maintained plugins solving complex problems.
The point isn't that plugins are bad. The point is that a lot of them solve problems that PHP solved decades ago. The Disable Comments plugin has a million installs. Classic Editor has five million. These are features that WordPress could (and arguably should) handle with a settings toggle.
Every plugin you don't install is one less thing that can break, one less thing to update, and one less potential security hole. For a full optimization strategy, start with the snippets above and build from there.
Next time you reach for a plugin, ask yourself: is this a one-liner? If yes, skip the install.
If your WordPress site is drowning in plugins and you need someone to clean it up, let's talk.
About the Author
Kemal Esensoy
Kemal Esensoy, founder of Wunderlandmedia, started his journey as a freelance web developer and designer. He conducted web design courses with over 3,000 students. Today, he leads an award-winning full-stack agency specializing in web development, SEO, and digital marketing.