Drupal Modules – Introduction (Foundations)

This article explains what Drupal modules are, how they work internally, and how Drupal loads and executes them. It covers:

  • A beginner-friendly explanation of modules
  • How modules are discovered and enabled
  • Key files every module uses
  • How hooks, services, and event subscribers fit in
  • References to real Drupal core files
  • Where modules sit in the request lifecycle
  • Real-world developer use cases

Understanding modules is core Drupal knowledge. Every feature you build, extend, or debug eventually touches a module.


1. What Is a Drupal Module? (Beginner Friendly)

A module is a self-contained package of code that adds, changes, or removes functionality in Drupal.

Examples:

  • Add a contact form
  • Alter how nodes are displayed
  • Integrate Salesforce or Elasticsearch
  • Add cron jobs
  • Modify routing, permissions, or access
  • Change how data is stored or rendered

Think of modules as plugins that hook into Drupal’s core system.

Drupal core itself is just a collection of modules.


2. Types of Drupal Modules

Drupal supports three main types:

Core Modules

Shipped with Drupal core
Examples:

  • node
  • user
  • views
  • system
  • field

Location:

core/modules/

Contributed Modules

Downloaded from drupal.org
Examples:

  • webform
  • token
  • pathauto
  • redis
  • search_api

Location:

modules/contrib/

Custom Modules

Written by you for project-specific logic

Location:

modules/custom/

This separation keeps core clean and upgrades safe.


3. The Minimal Module Structure

Every Drupal module must have at least one file:

example_module.info.yml

example_module.info.yml

name: Example Module
type: module
description: Adds custom functionality.
core_version_requirement: ^10
package: Custom

This file tells Drupal:

  • The module name
  • That it is a module
  • Which Drupal versions it supports

Without this file, Drupal will not detect the module.


4. How Drupal Discovers Modules

During cache rebuild or installation, Drupal scans module directories.

Discovery logic lives in:

core/lib/Drupal/Core/Extension/ExtensionDiscovery.php

Drupal:

  1. Scans core/modules, modules/contrib, modules/custom
  2. Reads .info.yml files
  3. Builds a module list
  4. Stores metadata in cache

That’s why after adding a module you must run:

drush cr

No cache rebuild = Drupal doesn’t know the module exists.


5. Enabling a Module

When you enable a module:

  • Dependencies are checked
  • Schema is installed
  • Services are registered
  • Hooks become active

Enable via UI or CLI:

drush en example_module

Under the hood, this is handled by:

core/lib/Drupal/Core/Extension/ModuleInstaller.php

Key steps:

  • Validate dependencies
  • Run .install hooks
  • Update module status in config
  • Rebuild container if needed

6. Common Module Files (What They Do)

example_module.module

Used for hooks.

function example_module_help($route_name, $route_match) {
  return 'Help text';
}

Hooks let modules react to Drupal events without modifying core.


example_module.install

Used for install, update, uninstall logic.

function example_module_install() {
  // Create tables, config, or default content.
}

Update hooks live here:

example_module_update_9001()

example_module.routing.yml

Defines custom routes.

example_module.page:
  path: '/example'
  defaults:
    _controller: '\\Drupal\\example_module\\Controller\\ExampleController::page'
    _title: 'Example Page'
  requirements:
    _permission: 'access content'

Routing ties URLs to controllers.


example_module.services.yml

Registers services in Drupal’s DI container.

services:
  example_module.helper:
    class: Drupal\\example_module\\Helper\\ExampleHelper

Services are reusable, testable, and clean.


7. Hooks – How Modules Interact

Hooks are function-based extension points.

Example:

function example_module_node_view(array &$build, NodeInterface $node) {
  $build['#attached']['library'][] = 'example_module/example';
}

Drupal calls hooks dynamically using:

core/lib/Drupal/Core/Extension/ModuleHandler.php

This allows:

  • Multiple modules to react to the same event
  • Ordered execution
  • Zero core hacks

8. Modules in the Request Lifecycle

Where modules fit in the request flow:

index.php
 → DrupalKernel boot
   → Load enabled modules
   → Register services
   → Register routes
   → Attach event subscribers
 → Routing
 → Controller execution
 → Hooks + services
 → Render pipeline
 → Response

Modules influence:

  • Routing
  • Access control
  • Controllers
  • Rendering
  • Caching
  • API calls

They are active throughout the entire request.


9. Modules vs Themes (Important Difference)

ModuleTheme
Controls behaviorControls presentation
PHP, YAML, servicesTwig, CSS, JS
Business logicUI and layout
APIs, data, routingHTML output

Rule of thumb:

  • Logic → module
  • Look & feel → theme

10. Real-World Developer Use Cases

Modules are used to:

  • Integrate Salesforce APIs
  • Push data to Elasticsearch
  • Create custom admin tools
  • Build REST/JSON endpoints
  • Handle cron and background jobs
  • Add Redis or cache logic
  • Extend Webforms
  • Implement security rules
  • Build multisite-specific behavior

Almost every enterprise Drupal feature lives in a custom module.


Why Modules Matter

Understanding modules helps you:

  • Debug “why is this happening?”
  • Trace unexpected behavior
  • Build clean, upgrade-safe features
  • Avoid hacking core or themes
  • Write scalable, testable code
  • Work confidently on large Drupal systems

If you understand modules, you understand Drupal.


Quick Summary

  • Modules add functionality to Drupal
  • Every module starts with .info.yml
  • Drupal discovers modules via directory scanning
  • Enabled modules register hooks, services, and routes
  • Hooks allow modules to react to events
  • Modules participate in the full request lifecycle
  • Custom modules power most real-world Drupal systems