Complete Module Directory Tree
A complete Magento 2 module contains many files, each serving a specific purpose.
app/code/Vendor/Module/
├── registration.php # Component registration
├── etc/
│ ├── module.xml # Module declaration
│ ├── di.xml # Global DI configuration
│ ├── events.xml # Global event observers
│ ├── routes.xml # Route definitions (deprecated)
│ ├── crontab.xml # Cron job definitions
│ ├── webapi.xml # REST API routes
│ ├── acl.xml # ACL permissions
│ ├── system.xml # System configuration
│ ├── config.xml # Default configuration values
│ ├── email_templates.xml # Email template declarations
│ ├── indexers.xml # Indexer definitions
│ ├── queue_consumer.xml # Message queue consumers
│ ├── queue_publisher.xml # Message queue publishers
│ ├── queue_topology.xml # Message queue topology
│ ├── communication.xml # Message queue config
│ └── frontend/
│ ├── di.xml # Frontend DI config
│ ├── routes.xml # Frontend routes
│ ├── events.xml # Frontend observers
│ └── layout.xml # Layout file declarations
│ └── adminhtml/
│ ├── di.xml # Admin DI config
│ ├── routes.xml # Admin routes
│ ├── events.xml # Admin observers
│ ├── acl.xml # Admin ACL
│ └── menu.xml # Admin menu
│ └── webapi_rest/
│ └── di.xml # REST API config
│ └── webapi_graphql/
│ └── schema.graphql # GraphQL schema
├── Api/
│ ├── Data/
│ │ └── ItemInterface.php # Data transfer object interface
│ ├── ItemRepositoryInterface.php # CRUD repository interface
│ └── ItemManagementInterface.php # Business logic interface
├── Block/
│ ├── Item.php # Block class
│ └── Adminhtml/
│ └── Item.php # Admin block class
├── Controller/
│ ├── Index/
│ │ └── Index.php # Frontend controller
│ └── Adminhtml/
│ └── Item/
│ ├── Index.php # Admin grid controller
│ ├── NewAction.php # Admin form controller
│ ├── Save.php # Admin save controller
│ └── Delete.php # Admin delete controller
├── Cron/
│ └── Cleanup.php # Cron job class
├── Model/
│ ├── Item.php # Model class
│ ├── ItemFactory.php # (generated) Factory
│ ├── ResourceModel/
│ │ └── Item.php # Resource model (DB operations)
│ └── ResourceModel/
│ └── Item/
│ └── Collection.php # Collection class
├── Observer/
│ └── ItemSave.php # Event observer
├── Plugin/
│ ├── ProductAfterSave.php # After plugin
│ ├── ProductBeforeSave.php # Before plugin
│ └── ProductAroundSave.php # Around plugin
├── Service/
│ └── ItemService.php # Business service class
├── Setup/
│ ├── InstallSchema.php # Schema installer
│ ├── UpgradeSchema.php # Schema upgrader
│ ├── InstallData.php # Data installer
│ └── UpgradeData.php # Data upgrader
├── View/
│ ├── frontend/
│ │ ├── layout/
│ │ │ ├── default.xml # Default layout
│ │ │ ├── catalog_product_view.xml # Product page layout
│ │ │ └── vendor_module_index_index.xml # Custom page layout
│ │ ├── templates/
│ │ │ └── item/
│ │ │ └── list.phtml # Template file
│ │ ├── web/
│ │ │ ├── css/
│ │ │ │ └── source/
│ │ │ │ └── _module.less # LESS source
│ │ │ ├── js/
│ │ │ │ └── custom.js # JavaScript
│ │ │ └── images/
│ │ │ └── logo.png # Image assets
│ │ └── requirejs-config.js # RequireJS mapping
│ ├── adminhtml/
│ │ ├── layout/
│ │ │ └── vendor_module_item_index.xml
│ │ ├── templates/
│ │ └── ui_component/
│ │ └── item_listing.xml # UI component grid
│ └── base/
│ └── web/
│ └── css/
│ └── _module.less # Base styles
├── i18n/
│ ├── en_US.csv # English translations
│ └── fr_FR.csv # French translations
├── Test/
│ ├── Unit/
│ │ └── Model/
│ │ └── ItemTest.php # Unit tests
│ └── Integration/
│ └── Model/
│ └── ItemRepositoryTest.php # Integration tests
└── composer.json # Composer package definition
Total files: 50+ in a complete module.
Core Module Files Explained
Understanding each core file's purpose is essential for building complete modules.
registration.php:
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Vendor_Module',
__DIR__
);
module.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_Module" setup_version="1.0.0">
<sequence>
<module name="Magento_Catalog"/>
</sequence>
</module>
</config>
di.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Vendor\Module\Service\ItemService">
<arguments>
<argument name="batchSize" xsi:type="number">100</argument>
</arguments>
</type>
<type name="Magento\Catalog\Model\ProductRepository">
<plugin name="vendor_product_after_save"
type="Vendor\Module\Plugin\ProductAfterSave"
sortOrder="10"/>
</type>
</config>
Model class:
<?php
namespace Vendor\Module\Model;
use Magento\Framework\Model\AbstractModel;
use Vendor\Module\Api\Data\ItemInterface;
class Item extends AbstractModel implements ItemInterface
{
const ENTITY_ID = 'entity_id';
const NAME = 'name';
const STATUS = 'status';
protected function _construct()
{
$this->_init(\Vendor\Module\Model\ResourceModel\Item::class);
}
public function getEntityId(): ?int
{
return $this->getData(self::ENTITY_ID);
}
public function getName(): ?string
{
return $this->getData(self::NAME);
}
}
Resource Model:
<?php
namespace Vendor\Module\Model\ResourceModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class Item extends AbstractDb
{
protected function _construct()
{
$this->_init('vendor_module_items', 'entity_id');
}
}
Module Configuration Files
Each configuration file in etc/ serves a specific purpose in the module lifecycle.
Routes (etc/frontend/routes.xml):
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="vendor_module" frontName="vendormodule">
<module name="Vendor_Module"/>
</route>
</router>
</config>
Events (etc/events.xml):
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_product_save_after">
<observer name="vendor_product_after_save"
instance="Vendor\Module\Observer\ItemSave"/>
</event>
</config>
Cron (etc/crontab.xml):
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="vendor_cleanup"
instance="Vendor\Module\Cron\Cleanup"
method="execute">
<schedule>0 2 * * *</schedule>
</job>
</group>
</config>
REST API (etc/webapi.xml):
<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route url="/V1/items/:itemId" method="GET">
<service class="Vendor\Module\Api\ItemRepositoryInterface" method="getById"/>
<resources><resource ref="anonymous"/></resources>
</route>
</routes>
ACL (etc/acl.xml):
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Vendor_Module::menu" title="Vendor Module">
<resource id="Vendor_Module::items" title="Manage Items"/>
</resource>
</resource>
</resources>
</acl>
</config>
Module Lifecycle and Best Practices
Building a complete module follows a lifecycle from creation to production deployment.
Development lifecycle:
# 1. Create module structure
mkdir -p app/code/Vendor/Module/{etc,Model,Block,Controller}
# 2. Create registration.php
# 3. Create module.xml
# 4. Create etc/di.xml
# 5. Develop module functionality
# 6. Run setup:upgrade
php bin/magento setup:upgrade
# 7. Compile DI
php bin/magento setup:di:compile
# 8. Deploy static content
php bin/magento setup:static-content:deploy
# 9. Clean cache
php bin/magento cache:clean
Production deployment checklist:
# Switch to production mode
php bin/magento deploy:mode:set production
# Compile DI
php bin/magento setup:di:compile
# Deploy static content
php bin/magento setup:static-content:deploy -f
# Clean and warm cache
php bin/magento cache:clean
php bin/magento cache:warmup
# Enable maintenance mode if needed
php bin/magento maintenance:enable
php bin/magento maintenance:disable
Module file summary:
| File | Purpose |
|---|---|
| registration.php | Register component |
| module.xml | Declare module |
| di.xml | DI configuration |
| events.xml | Observer registration |
| routes.xml | URL routing |
| crontab.xml | Scheduled tasks |
| webapi.xml | REST API routes |
| acl.xml | Permissions |
| system.xml | Admin config |
| Setup/*.php | DB schema/data |
Best practices:
- Keep modules focused on single responsibility
- Use interfaces for all service contracts
- Follow Magento coding standards
- Write tests for business logic
- Use plugins over events for method modification
- Keep di.xml clean with virtual types
- Version modules properly with setup_version
Quiz
1. What is the minimum set of files for a Magento 2 module?
2. Which file defines REST API routes in a module?
3. Where do database schema scripts go?
Flashcards
Question
What are the 10+ XML files in a complete module's etc/ directory?
Click to reveal answer
Answer
module.xml, di.xml, events.xml, routes.xml, crontab.xml, webapi.xml, acl.xml, system.xml, config.xml, email_templates.xml, and area-specific variants
Question
What does the Setup/ directory contain?
Click to reveal answer
Answer
InstallSchema.php, UpgradeSchema.php, InstallData.php, UpgradeData.php
Question
Where do admin controllers go?
Click to reveal answer
Answer
Controller/Adminhtml/{Entity}/{Action}.php
Question
What is the purpose of Api/ directory?
Click to reveal answer
Answer
Service contract interfaces for external API exposure
Revision Notes
Key Takeaways
- 1. Complete modules have 50+ files across multiple directories
- 2. registration.php and module.xml are the minimum required files
- 3. etc/ contains all XML configuration files
- 4. Model/ handles business logic, Controller/ handles requests
- 5. Setup/ manages database schema and data migrations
- 6. Api/ defines service contracts for API exposure
- 7. View/ contains templates, layouts, CSS, and JavaScript
- 8. Follow Magento coding standards and best practices
Interview Tips
- • Draw a complete module directory tree from memory
- • Explain the purpose of each etc/ XML file
- • Describe the Model-ResourceModel-Collection pattern
- • Discuss service contracts and their importance
- • Know the development lifecycle from creation to deployment
- • Explain how to create a complete module from scratch
Cheat Sheet
Module Architecture Cheat Sheet
Core Files:
- registration.php → Component registration
- etc/module.xml → Module declaration
- etc/di.xml → DI configuration
Model Pattern:
Model/Item.php → Business logic
Model/ResourceModel/Item.php → DB operations
Model/ResourceModel/Item/Collection.php → Query builder
etc/ Files:
module.xml, di.xml, events.xml, routes.xml, crontab.xml, webapi.xml, acl.xml, system.xml, config.xml
Setup/ Files:
InstallSchema.php, UpgradeSchema.php, InstallData.php, UpgradeData.php
View/ Structure:
view/{area}/layout/ → Layout XML
view/{area}/templates/ → PHP templates
view/{area}/web/css/ → Stylesheets
view/{area}/web/js/ → JavaScript