Odoo is built entirely around a modular architecture. Every feature in the system — from sales and accounting to inventory and e-commerce — is implemented as a module. Custom development in Odoo means building your own modules or extending existing ones.
Understanding modules is the essential first step to working with Odoo as a developer.
What is an Odoo Module?
A Module in Odoo is a package that can contain multiple models, views, controllers, security rules, and other components that together provide a specific functionality or feature set.
Modules are the building blocks of an Odoo application. They can be installed or removed from an Odoo instance independently, and they can depend on other modules to extend or reuse their functionality.
+----------------------------------------------+
| Odoo Application |
| |
| +----------+ +----------+ +----------+ |
| | Module A | | Module B | | Module C | |
| | (Sales) | | (Stock) | | Custom) | |
| +----------+ +----------+ +----------+ |
| | | | |
| +--------------+--------------+ |
| | |
| Base Module (Odoo Core) |
+----------------------------------------------+
Each module is isolated but can declare dependencies on other modules to inherit and extend their functionality.
Module Structure
To create a module, you create a directory inside the Odoo add-ons path. The directory must follow a specific structure to be recognized by Odoo:
my_module/
├── __init__.py
├── __manifest__.py
├── models/
│ ├── __init__.py
│ └── product.py
├── views/
│ └── product_views.xml
└── security/
└── ir.model.access.csv
File and Directory Breakdown
| Path | Purpose |
|---|---|
__init__.py | Makes the directory a Python package; imports submodules |
__manifest__.py | Declares module metadata, dependencies, and data files |
models/ | Python files defining database models and business logic |
views/ | XML files defining UI elements (forms, lists, menus) |
security/ | Access control rules defining who can read/write data |
As a module grows, additional directories may be added:
my_module/
├── __init__.py
├── __manifest__.py
├── models/
├── views/
├── security/
├── controllers/ # HTTP routes (website or API)
├── static/ # CSS, JS, images
├── data/ # Default/demo data (XML or CSV)
├── wizards/ # Transient model dialogs
└── report/ # PDF report templates
The `__manifest__.py` File
The manifest is the most important file in any Odoo module. It declares all metadata that Odoo needs to load, install, and manage the module.
# -*- coding: utf-8 -*-
{
'name': "Code Highlight - VarApps",
'version': "17.0.1.0", # <Compatible Odoo Version>.<Module Version>
'category': "Website", # Module category shown in Apps menu
'license': 'OPL-1',
'summary': "Code block highlighting for Odoo website",
'description': """
A highlight module that adds a new block for code
and uses prism to color the code in Odoo website.
""",
'author': "VarApps",
'website': "https://www.varapps.com",
'company': 'Varapps Software Solutions',
'maintainer': 'Varapps Software Solutions',
'depends': ['base'], # Modules this module depends on
# Data files loaded at installation
'data': [],
# Demonstration data (optional)
'demo': [],
'installable': True,
'auto_install': False,
'application': False,
}
Key Manifest Fields
| Field | Description |
|---|---|
name | Human-readable module name shown in the Apps menu |
version | Version string — first part should match Odoo version (e.g. 17.0) |
category | Category used to group the module in the Apps menu |
summary | One-line description shown below the module name |
description | Longer description (supports RST format) |
depends | List of module names this module requires to be installed first |
data | List of XML/CSV files to load when the module is installed |
demo | List of files loaded only in demo mode |
installable | Whether the module can be installed via the Apps menu |
auto_install | If True, the module installs automatically when all its dependencies are installed |
application | If True, the module appears as a top-level app with its own menu |
The `depends` Field
The depends list is critical. It defines which modules must be installed before this one. Odoo will refuse to install your module if any dependency is missing.
'depends': ['base', 'sale', 'stock'],
Common dependencies:
| Module | Description |
|---|---|
base | Core Odoo module — almost always required |
sale | Sales module |
purchase | Purchase module |
stock | Inventory/stock module |
account | Accounting module |
website | Website builder module |
mail | Messaging and chatter features |
The `__init__.py` Files
Every Python package needs an __init__.py. In Odoo modules, these files are used to import submodules so that Python recognizes them.
Root __init__.py:
# my_module/__init__.py
from . import models
Models __init__.py:
# my_module/models/__init__.py
from . import product
from . import sale_order
Odoo loads models by importing these packages, so forgetting to add a model to __init__.py means it will not be registered.
The `data` List
The data field in the manifest lists XML and CSV files that are loaded when the module is installed or updated. These files can define:
- Default records (product categories, configuration settings)
- UI elements (views, menus, actions)
- Security rules (access control lists)
'data': [
'security/ir.model.access.csv',
'views/product_views.xml',
'data/default_data.xml',
],
Files are loaded in the order they are listed, which matters when records reference each other.
Security: Access Control
The ir.model.access.csv file defines which user groups have read, write, create, and delete access to each model.
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_my_model,access.my.model,model_my_model,base.group_user,1,1,1,0
| Column | Description |
|---|---|
id | Unique external ID for this access rule |
name | Descriptive name |
model_id:id | Reference to the model (model_ + model name with dots replaced by underscores) |
group_id:id | User group that gets this access (or leave empty for all users) |
perm_read | 1 = allow read, 0 = deny |
perm_write | 1 = allow write |
perm_create | 1 = allow create |
perm_unlink | 1 = allow delete |
Installing a Module
Once your module is created and placed in the Odoo add-ons directory, follow these steps to install it:
- Restart the Odoo server to pick up new files
- Go to the Apps menu in the Odoo backend
- Click Update App List to refresh the list of available modules
- Search for your module by name
- Click Install
To update an already-installed module after making code changes:
# Restart with update flag
./odoo-bin -u my_module -d my_database
Module Development Workflow
1. Create module directory
|
v
2. Write __manifest__.py
|
v
3. Define models in models/
|
v
4. Create views in views/
|
v
5. Add security rules in security/
|
v
6. Restart Odoo server
|
v
7. Update app list and install
|
v
8. Test and iterate
Final Thoughts
The Odoo module system is elegant in its design. By following a consistent directory structure and manifest format, Odoo knows how to load, register, and manage any custom code you write.
Mastering the module structure is the gateway to all Odoo development — whether you are building new business features, customizing existing ones, or creating reusable packages to share across projects.
Every Odoo customization starts with a module.