Most WordPress plugins work fine… until they don’t.
A site breaks after deactivation.
Old data stays forever after uninstall.
A database fills up with junk no one asked for.
None of this is accidental. It happens because activation, deactivation, and uninstall are treated as afterthoughts. Here’s the thing: these three moments define how “professional” your plugin feels. Not the UI. Not the feature list. These lifecycle hooks decide whether site owners trust you or regret installing your plugin.
Let’s walk through each one—slowly, clearly, and with real intent.
Why These Three Hooks Matter More Than You Think
A plugin doesn’t live forever.
People test it.
They disable it temporarily.
They remove it when requirements change.
If your plugin:
- Breaks the site on activation
- Leaves junk after uninstall
- Deletes data without warning
you’ve already lost the user—even if the plugin was technically good.
So the rule is simple:
Activation = prepare
Deactivation = pause safely
Uninstall = clean up responsibly
Let’s break each part down.
Plugin Activation: Set Things Up, Don’t Do Too Much
Activation runs once, right when the user clicks “Activate”.
This is not the place for heavy logic.
What Activation Is For
Use activation to:
- Create required database tables
- Set default options
- Check minimum requirements (PHP, WordPress version)
- Prepare rewrite rules if needed
That’s it.
Activation should be fast and predictable. If it takes too long or throws errors, WordPress will disable your plugin immediately.
What Activation Should NOT Do
Avoid:
- Sending emails
- Creating demo content without consent
- Running long database migrations
- Making external API calls
If something takes time, handle it later using background processes or admin notices.
A Simple Activation Example
register_activation_hook( __FILE__, 'my_plugin_activate' );
function my_plugin_activate() {
if ( version_compare( PHP_VERSION, '7.4', '<' ) ) {
deactivate_plugins( plugin_basename( __FILE__ ) );
wp_die( 'This plugin requires PHP 7.4 or higher.' );
}
add_option( 'my_plugin_version', '1.0.0' );
}
Clean. Predictable. Safe.
Creating Database Tables on Activation
If your plugin needs custom tables, activation is the right place.
Use dbDelta() and always check if the table already exists. Never assume a fresh install.
Also, store the plugin version in the database. You’ll need it later for updates.
Deactivation: Pause Without Breaking Anything
Deactivation happens when a user clicks “Deactivate”. This is not uninstall.
Think of deactivation as:
“I might come back later.”
So your job is to stop running—not to delete everything.
What Deactivation Is For
Good uses:
- Remove scheduled cron jobs
- Clear temporary caches
- Stop background processes
That’s it.
What Deactivation Should NOT Do
Do not:
- Delete user data
- Remove database tables
- Reset settings
- Remove user-generated content
If you delete data here, you’re asking for angry users.
A Deactivation Example
register_deactivation_hook( __FILE__, 'my_plugin_deactivate' );
function my_plugin_deactivate() {
wp_clear_scheduled_hook( 'my_plugin_cron_event' );
}
Notice what’s missing: no deletes, no cleanup drama.
Just stopping what needs to stop.
Uninstall: Clean Up Like You Were Never There
Uninstall is the final goodbye.
This happens when:
- The user clicks “Delete” in the plugin list
- Or uses WP-CLI to uninstall the plugin
This is the only place where full cleanup makes sense.
Two Correct Ways to Handle Uninstall
WordPress supports:
uninstall.phpfile (recommended)register_uninstall_hook()(acceptable)
Use uninstall.php whenever possible. It’s clearer and safer.
Using uninstall.php (Best Practice)
Create a file named uninstall.php in your plugin root.
WordPress will run this file only when the plugin is being deleted.
Basic Safety Check
Always start with this:
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
exit;
}
This prevents accidental execution.
What to Remove on Uninstall
Only remove what your plugin created:
- Plugin options
- Custom tables (if appropriate)
- Plugin-specific user meta
- Plugin-specific post meta
Never delete:
- Posts you didn’t create
- User accounts
- Shared data used by other plugins
Example: Cleaning Options
delete_option( 'my_plugin_settings' );
delete_option( 'my_plugin_version' );
Example: Cleaning Custom Tables
global $wpdb;
$table = $wpdb->prefix . 'my_plugin_logs';
$wpdb->query( "DROP TABLE IF EXISTS $table" );
Simple. Direct. Respectful.
Give Users Control Over Data Deletion
Here’s where many plugins get this wrong.
Some users want:
- Full cleanup on uninstall
Others want:
- Data preserved, just in case
The solution is simple.
Add a setting:
“Delete all plugin data on uninstall”
Then check it during uninstall.
Example Logic
$delete_data = get_option( 'my_plugin_delete_data' );
if ( $delete_data ) {
delete_option( 'my_plugin_settings' );
}
This small detail builds trust.
Handling Updates vs Activation
A common mistake: using activation to handle updates.
Activation runs once. Updates happen many times.
Instead:
- Store plugin version
- Compare versions on load
- Run upgrade logic when needed
Simple Upgrade Pattern
$current_version = get_option( 'my_plugin_version' );
if ( version_compare( $current_version, '1.1.0', '<' ) ) {
// Run update logic
update_option( 'my_plugin_version', '1.1.0' );
}
This keeps activation clean and updates safe.
Multisite Considerations
If your plugin supports multisite:
- Activation may run per site or network-wide
- Options may be site-level or network-level
Always check:
is_multisite()
And handle both cases properly. Never assume single-site behavior.
Common Mistakes to Avoid
Let’s call these out clearly.
- Running heavy logic on activation
- Deleting data on deactivation
- Forgetting uninstall cleanup
- Dropping tables without user consent
- Assuming uninstall will always run
- Mixing update logic with activation
Each of these causes real damage in production sites.
A Simple Mental Model
If you remember nothing else, remember this:
- Activation → Prepare the plugin
- Deactivation → Stop the plugin
- Uninstall → Remove the plugin
No overlap. No shortcuts.
Why This Matters for Real Products
If you’re building:
- A WooCommerce extension
- An LMS plugin
- A SaaS-connected plugin
- Anything used on real businesses
Your plugin lifecycle is part of your reputation.
Site owners talk.
Support tickets pile up.
Bad decisions here cost you users.
Doing this right doesn’t make your plugin flashy.
It makes it trusted.
And trust is what keeps plugins installed long-term.
Final Thoughts
Plugin activation, deactivation, and uninstall aren’t advanced because they’re complex. They’re advanced because they require restraint.
Knowing what not to do is the real skill.
Handle these three moments properly, and your plugin will feel solid, respectful, and professional—even before users notice your features.
That’s how good WordPress plugins are built.