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:

  1. Part 1: Create your first module
  2. Part 2: Models and fields
  3. Part 3: Security and access rights
  4. Part 4: Menus, actions, and views
  5. Part 5: Relations, computed fields, and business logic
  6. 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/
odoo/
custom-addons/

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
cd ~/odoo-dev/custom-addons/estate

Now create the minimum files Odoo expects:

touch __init__.py __manifest__.py
mkdir models
mkdir security
mkdir views
touch models/__init__.py

At this point your module should look like this:

estate/
__init__.py
__manifest__.py
models/
__init__.py
security/
views/

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:

{
'name': 'Estate',
'version': '1.0',
'summary': 'Real estate management training module',
'sequence': 10,
'description': 'Custom training module for learning Odoo development.',
'category': 'Tutorials',
'author': 'Your Name',
'depends': ['base'],
'data': [],
'installable': True,
'application': True,
'license': 'LGPL-3',
}

Important fields:

  • depends: modules that must be installed before this module
  • data: XML, CSV, and other files Odoo should load
  • application: if True, 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]
addons_path = /Users/yourname/odoo-dev/odoo/addons,/Users/yourname/odoo-dev/custom-addons
admin_passwd = admin
xmlrpc_port = 8069
db_host = False
db_port = False
db_user = your_macos_username
db_password = False

Replace these values:

  • /Users/yourname/odoo-dev/odoo with your actual Odoo source path
  • /Users/yourname/odoo-dev/custom-addons with your actual custom addons path
  • your_macos_username with 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
source .venv/bin/activate

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:

  1. Open the Apps menu.
  2. Search for Estate.
  3. If you do not see it, remove the default Apps filter.
  4. 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__.py exists and is valid Python syntax
  • the addons_path includes 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_user in odoo.conf matches 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

Md. Monirul Alom

Md. Monirul Alom

I am a Full Stack Web developer. I love to code, travel, do some volunteer work. Whenever I get time I write for this blog