Odoo Custom Module Development Part 1 - Create Your First Module
This is the first article in a practical series on Odoo custom module development.
In this series, we will build a small real estate application called estate. The goal is not just to make the module work, but to understand how Odoo modules are structured and how to develop them cleanly.
Series roadmap:
- Part 1: Create your first module
- Part 2: Models and fields
- Part 3: Security and access rights
- Part 4: Menus, actions, and views
- Part 5: Relations, computed fields, and business logic
- Part 6: Reports, demo data, and tests
Before starting, make sure your Odoo development environment is already running on macOS. If not, read the Odoo installation article first.
What we are going to build
We will create a custom module named estate that manages property records. Later, we will add:
- models
- fields
- menus
- views
- security rules
- reports
- tests
In this article, we will only create the module skeleton and make Odoo recognize it.
1. Create a custom addons directory
Keep custom modules outside the main Odoo source tree. This makes upgrades and Git workflows much easier.
Example directory structure:
~/odoo-dev/ |
Create the custom addons directory:
mkdir -p ~/odoo-dev/custom-addons |
If your Odoo source code is not in ~/odoo-dev/odoo, adjust the paths in the rest of this guide.
2. Create the module folder
Inside custom-addons, create a folder for the module:
mkdir -p ~/odoo-dev/custom-addons/estate |
Now create the minimum files Odoo expects:
touch __init__.py __manifest__.py |
At this point your module should look like this:
estate/ |
3. Write the module manifest
The __manifest__.py file tells Odoo what the module is, what it depends on, and which data files to load.
Open __manifest__.py and add:
{ |
Important fields:
depends: modules that must be installed before this moduledata: XML, CSV, and other files Odoo should loadapplication: ifTrue, the module appears as an app in the Apps menu
For now, base is enough.
4. Configure Odoo to load custom addons
Odoo must know where your custom module folder is.
Create a config file, for example ~/odoo-dev/odoo.conf:
[options] |
Replace these values:
/Users/yourname/odoo-dev/odoowith your actual Odoo source path/Users/yourname/odoo-dev/custom-addonswith your actual custom addons pathyour_macos_usernamewith your macOS username
If you already use another config file, just update its addons_path.
5. Start Odoo with the config file
Go to the Odoo source directory:
cd ~/odoo-dev/odoo |
Run Odoo with your config file:
python3 odoo-bin -c ~/odoo-dev/odoo.conf -d odoo19 |
Open this URL:
http://localhost:8069 |
If the database is valid and the server starts, continue to the next step.
6. Update the Apps list
Odoo does not always show newly created modules until the Apps list is refreshed.
In the browser:
- Open the Apps menu.
- Search for
Estate. - If you do not see it, remove the default
Appsfilter. - Click the app menu and update the app list if needed.
If everything is correct, your new Estate app should appear.
7. Install the module
Click Install from the Odoo interface.
You can also install it from the command line:
python3 odoo-bin -c ~/odoo-dev/odoo.conf -d odoo19 -i estate --stop-after-init |
This is useful when you want a repeatable development workflow.
8. Common development commands
Install a module:
python3 odoo-bin -c ~/odoo-dev/odoo.conf -d odoo19 -i estate --stop-after-init |
Upgrade a module after code changes:
python3 odoo-bin -c ~/odoo-dev/odoo.conf -d odoo19 -u estate --stop-after-init |
Run the server normally:
python3 odoo-bin -c ~/odoo-dev/odoo.conf -d odoo19 |
9. Typical mistakes in this step
The module does not appear in Apps
Check these items:
- the module folder is inside your custom addons path
__manifest__.pyexists and is valid Python syntax- the
addons_pathincludes the custom addons directory - the app list has been refreshed
Odoo fails to start
Check:
- the Python virtual environment is activated
- PostgreSQL is running
- the database name in the command exists
- the
db_userinodoo.confmatches your local PostgreSQL user
ModuleNotFoundError
This usually means your Python dependencies are incomplete. Reinstall requirements from the Odoo source directory:
pip install -r requirements.txt |
Final words
You now have a valid Odoo module skeleton and a repeatable setup for loading custom addons.
In the next article, we will create actual models and fields inside the estate module.
Next article: Odoo Custom Module Development Part 2 - Models and Fields
Related posts
- /article/odoo-custom-module-development-part-2-models-and-fields/
- /article/how-to-install-odoo-macos/
- /article/odoo-custom-module-development-part-5-relations-computed-fields-and-business-logic/
- /article/odoo-custom-module-development-part-6-reports-demo-data-and-tests/
- /article/odoo-custom-module-development-part-4-menus-actions-and-views/