Drupal provides multiple extension mechanisms that allow modules to react to system behavior. Two of the most important are hooks and event subscribers. Understanding when to use each is critical to writing clean, maintainable, and scalable Drupal code.
Drupal 7 relied almost entirely on hooks. Starting with Drupal 8, Drupal introduced Symfony’s EventDispatcher and adopted event subscribers as a first class architectural pattern.
The focus here is architectural decision making, not syntax memorization.
Why This Comparison Belongs in Core Architecture
Choosing between hooks and event subscribers affects:
- Code structure
- Coupling between modules
- Testability
- Execution order
- Long term maintainability
Drupal core itself uses both patterns deliberately. Understanding why is essential for senior level Drupal development.
What Are Hooks
Hooks are procedural functions that allow modules to participate in Drupal processes.
Characteristics of hooks:
- Procedural functions
- Discovered by naming convention
- Executed in module order
- Widely used in entity and form lifecycles
Example hook:
function my_module_entity_presave(\Drupal\Core\Entity\EntityInterface $entity) {
}
Hooks are deeply integrated into Drupal core APIs.
What Are Event Subscribers
Event subscribers are object oriented services that listen to dispatched events.
Characteristics of event subscribers:
- Implement EventSubscriberInterface
- Registered as services
- Use dependency injection
- Execute based on priority
Subscribers respond to events. They do not control execution flow directly.
Architectural Differences
Discovery
Hooks:
- Discovered by function name
- Requires module to be enabled
Event subscribers:
- Discovered via service container
- Registered using service tags
Execution Order
Hooks:
- Executed in module weight order
- Limited control over priority
Event subscribers:
- Executed by numeric priority
- Fine grained ordering control
Dependency Management
Hooks:
- No constructor injection
- Must fetch services manually
Event subscribers:
- Full dependency injection
- Explicit dependencies
Testability
Hooks:
- Harder to unit test
- Often rely on globals
Event subscribers:
- Easier to unit test
- Can be mocked and isolated
When Hooks Are the Right Choice
Hooks are preferred when:
- Working with entity lifecycle events
- Altering forms or form elements
- Integrating with legacy APIs
- Implementing required core extension points
Examples:
- hook_entity_presave
- hook_form_alter
- hook_theme
These hooks are stable and expected by Drupal core.
When Event Subscribers Are the Right Choice
Event subscribers are preferred when:
- Reacting to request lifecycle events
- Modifying responses
- Handling cross cutting concerns
- Coordinating behavior across modules
Examples:
- Kernel request handling
- Response modification
- Redirect logic
- Header manipulation
Subscribers excel at system wide behavior.
Side by Side Example
Hook Based Approach
function my_module_init() {
// Deprecated pattern
}
Event Subscriber Approach
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
class ExampleSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [
KernelEvents::REQUEST => 'onRequest',
];
}
}
This illustrates the shift from procedural to event driven architecture.
Coexistence in Drupal Core
Drupal core intentionally uses both systems.
Examples:
- Entity API relies heavily on hooks
- Routing and request handling rely on events
- Rendering uses both hooks and events
This hybrid model balances backward compatibility and modern design.
Common Mistakes
- Replacing hooks unnecessarily with events
- Using events for entity CRUD logic
- Overusing kernel events
- Fetching services statically in subscribers
- Mixing responsibilities
Architecture decisions matter more than syntax.
Drupal 10 and 11 Best Practices
- Use hooks where core expects hooks
- Use event subscribers for cross cutting concerns
- Keep subscribers small and focused
- Inject dependencies properly
- Avoid duplicating logic across both systems
Acquia Exam Notes and Cheat Sheet
Key concepts to remember:
- Hooks are procedural and discovered by naming
- Event subscribers are services
- Subscribers execute based on priority
- Hooks execute based on module order
- Both systems coexist intentionally
Common exam traps:
- Assuming hooks are deprecated
- Thinking subscribers replace all hooks
- Forgetting event_subscriber service tag
- Confusing kernel events with entity hooks
Quick decision guide:
- Entity or form lifecycle change: hook
- Request or response behavior: event subscriber
- Cross module coordination: event subscriber
- Required core API integration: hook
If the question asks about HTTP lifecycle, events are the answer.
Summary
Hooks and event subscribers serve different architectural purposes in Drupal. Hooks remain essential for core APIs and data lifecycle integration, while event subscribers enable decoupled, event driven system behavior. Mastering when to use each is a hallmark of advanced Drupal architecture knowledge and is frequently tested in Acquia certification exams.
This article sets the stage for deeper topics such as request and response lifecycle, event propagation, and plugin based extension patterns.