Jump to content

ICT:D Cleaning up Unused Custom Modules (Composer - Drush)

From Costa Sano MediaWiki

Drupal: Cleaning Up Unused Custom Modules (Composer + Drush)

Purpose

This page documents the **correct and safe procedure** for removing unused or experimental **custom Drupal modules**, including:

  • database cleanup
  • configuration cleanup
  • file system cleanup

The procedure avoids common pitfalls and is suitable for long‑lived Drupal installations that must remain upgrade‑safe.

---

Important Principles

Drupal deliberately separates:

Aspect Managed by
Module enable/disable Drupal
Configuration & schema cleanup Module uninstall logic
Module files on disk You / Composer

Drupal never deletes module files automatically. This is a security and deployment design choice.

---

Never Do This

  • ❌ Do NOT delete module files before uninstalling
  • ❌ Do NOT drop tables while the module is still enabled
  • ❌ Do NOT rely on Drupal to clean up experimental schema automatically

Doing so may leave broken configuration or database artifacts.

---

Correct Cleanup Procedure

Step 1: Verify the Module Is No Longer Used

Before removal, ensure:

  • no content depends on the module
  • no fields, entities, or views reference it
  • no other module lists it as a dependency

---

Step 2: Uninstall the Module (Mandatory)

Uninstalling runs:

  • hook_uninstall()
  • configuration cleanup
  • entity cleanup (if implemented correctly)

Using Drush (recommended)

drush pmu my_custom_module

Using the Admin UI

  • Go to Extend → Uninstall
  • Select the module
  • Confirm uninstall

Note: Disabling a module is NOT sufficient. You must uninstall it.

---

Step 3: Remove the Module Files

Drupal will NOT remove files from disk.

Custom module (manual)

rm -rf modules/custom/my_custom_module

Contrib module (Composer-managed)

composer remove drupal/my_module

This removes:

  • the module directory
  • composer.json / composer.lock references

---

Step 4: Clear Caches

After file removal:

drush cr

This ensures Drupal no longer tries to discover the module.

---

Database Cleanup (If Needed)

Custom Tables

Drupal does NOT drop custom tables automatically unless explicitly coded.

If the module created a “real” join table or custom schema:

DROP TABLE my_custom_join_table;

Only do this:

  • after uninstalling the module
  • when you are certain the table is unused

This is normal for experimental schema.

---

How to Check for Leftovers

Search the database for the module name:

grep my_custom_module database_dump.sql

Or inspect:

  • config
  • key_value
  • cache_* tables (usually cleared by cache rebuild)

---

Common Error Scenario

If files are deleted before uninstalling:

  • Drupal reports:
 “The following module is missing from the file system…”
  • Uninstall hooks never ran
  • Manual DB cleanup is required

This is why uninstall must always come first.

---

Why Drupal Works This Way

Drupal avoids automatic file deletion because:

  • web servers should not delete their own code
  • production file systems are often read‑only
  • deployments are controlled externally
  • safety is preferred over convenience

This design supports secure, professional deployments.

---

Architectural Lesson

Custom modules:

  • create lifecycle responsibility
  • require manual cleanup
  • increase long‑term maintenance cost

Configuration‑driven solutions:

  • leave no schema debris
  • uninstall cleanly
  • survive core upgrades

This cleanup step is not housekeeping — it is architectural alignment.

---

Summary Checklist

Step Required
Uninstall module (pmu) ✅ Yes
Remove module files ✅ Yes
Clear caches ✅ Yes
Drop custom tables (if any) ✅ Manual
Verify no leftovers ✅ Recommended

---

Final Note

Experimental work is valuable.

Cleaning it up properly:

  • preserves system integrity
  • simplifies upgrades
  • helps your successor
  • reflects professional discipline