A Complete Manifest Example
Here is a real, fully-annotated __manifest__.py covering every commonly-used key:
{
# ── Required keys ──────────────────────────────────────────────────────────
'name': 'Library Management', # Human-readable display name
'version': '19.0.1.0.0', # Format: odoo_version.major.minor.patch
# ── Metadata ───────────────────────────────────────────────────────────────
'summary': 'Manage your library books, members, and borrowings',
'description': """
Library Management System
=========================
Track books, members, borrowings, and returns.
Includes portal access for members to view their history.
""",
'author': 'Algorid Limited',
'website': 'https://algorid.com',
'category': 'Services/Library', # Apps menu category
'license': 'LGPL-3', # or OPL-1 for proprietary
# ── Dependencies ───────────────────────────────────────────────────────────
'depends': [
'base', # always required (implicitly, but explicit is better)
'mail', # for chatter / messaging
'portal', # for customer portal access
],
# ── Files to load ──────────────────────────────────────────────────────────
'data': [
'security/ir.model.access.csv',
'security/record_rules.xml',
'views/book_views.xml',
'views/member_views.xml',
'views/menus.xml',
'data/book_sequence.xml',
'report/book_report.xml',
],
'demo': [
'demo/demo_books.xml',
'demo/demo_members.xml',
],
# ── Web assets ─────────────────────────────────────────────────────────────
'assets': {
'web.assets_backend': [
'library_management/static/src/scss/library.scss',
'library_management/static/src/js/book_widget.js',
'library_management/static/src/xml/book_widget.xml',
],
'web.assets_frontend': [
'library_management/static/src/scss/portal.scss',
],
},
# ── App behaviour ──────────────────────────────────────────────────────────
'application': True, # Shows as a top-level app in Apps menu
'installable': True, # Can be installed (default True)
'auto_install': False, # Don't auto-install when all depends installed
}
Required Keys
name(string) — the display name shown in the Apps menu. Keep it short and clear.version(string) — must follow theodoo_version.major.minor.patchformat. The first number must match the Odoo major version (19 for Odoo 19). Increment the patch for bug fixes, minor for new features, major for breaking changes.
Dependencies
The depends key is a list of module technical names this module requires. Odoo loads dependencies first. If a dependency isn't installed, this module can't be installed either.
Always depend on base (the foundation). If you use the chatter, depend on mail. If you extend sale orders, depend on sale.
| Depend | Gives you |
|---|---|
base | Core models (res.partner, res.users, etc.) |
mail | Chatter, messaging, mail templates |
portal | Portal routes, portal user group |
sale | Sale orders, sale teams |
purchase | Purchase orders |
stock | Inventory, warehouses, stock moves |
account | Accounting, invoices, journals |
website | Public website, snippets, eCommerce |
point_of_sale | POS models and UI |
Data and Demo Keys
datalist — loaded on every install and upgrade, in order. Security CSV must come before views (the model must exist before access rules can reference it), views before menus, menus before actions.demolist — loaded only when demo data is enabled at database creation.- File paths are relative to the module root.
Odoo processes data files top-to-bottom. A file that references (via ref=) a record from a later file will raise "External ID not found". Always list security first, then views, then actions, then menus.
Assets Key (Odoo 14+)
The assets dict registers static files into asset bundles. Files added to a bundle are compiled and served together by Odoo's asset pipeline.
| Bundle | When loaded |
|---|---|
web.assets_backend | Backend (logged-in Odoo interface) |
web.assets_frontend | Frontend (public website, portal) |
web.assets_common | Both backend and frontend |
point_of_sale.assets | POS UI |
web.report_assets_common | QWeb PDF reports |
Metadata Keys
summary— one-line description shown under the module name in the Apps listdescription— long description (RST format supported); shown in the module info pageauthor— your name or company namewebsite— your website URLcategory— path like'Services/Library'or'Technical'— controls Apps menu groupinglicense—'LGPL-3'for open-source Community modules;'OPL-1'for proprietary/Enterprise modules
App Behaviour Keys
application: True— module appears as a top-level app tile (with an icon) in the Apps menu. Set to True only for modules that are the "main app" of a feature area.installable: True— module appears in the Apps list and can be installed. Set to False to hide a module (e.g. a base library module not meant to be installed directly).auto_install: False— if True, Odoo automatically installs this module when ALL of its dependencies are installed. Used for "glue modules" that add integration between two other modules (e.g.sale_stock, which adds stock features when bothsaleandstockare installed).
A glue module has auto_install: True and two or more dependencies. It is automatically installed when all its dependencies are present. The Odoo core uses this pattern extensively — for example, sale_stock bridges sale and stock with delivery-related fields on sale orders.
Version Numbering
The version format odoo_version.major.minor.patch (e.g. 19.0.1.0.0) is a community convention — not enforced by Odoo — but followed universally:
19— must match the Odoo major version1— major version of your module (increment for breaking changes)0— minor version (increment for new features)0— patch (increment for bug fixes)
| Part | When to increment |
|---|---|
Major (19) | Never during normal development — changes when you port to a new Odoo version |
2nd (1) | Module has breaking changes — data migration needed |
3rd (0) | New features added, backward compatible |
4th (0) | Bug fixes only |
📋 Key Points
nameandversionare the only truly required keys — Odoo will load a module without others, but best practice is to include all metadata keys.- The
dependslist determines load order — missing dependencies prevent installation entirely. datafiles load on every install and upgrade;demofiles load only with demo data. Load order withindatamatters — security first, then views, then actions, then menus.- The
assetsdict registers JS/SCSS/XML into bundles — useweb.assets_backendfor backend,web.assets_frontendfor portal/website. application: Trueadds a top-level app tile;auto_install: Truecreates a glue module that installs automatically when all its dependencies are present.
FAQ
data in an upgraded module? +Odoo will load the new file and create the records it defines. Existing records defined in existing files will also be reloaded and updated, unless wrapped in noupdate="1".
application: True and installable: True? +installable: True makes the module appear in the Apps list at all. application: True additionally gives it a main menu entry and an icon tile — it becomes a "top-level app". A module can be installable without being an application — most integration or extension modules are installable but not applications.
No. If a module in your depends list is not installed, your module cannot be installed either. Odoo checks all dependencies are available before allowing installation.
A module with auto_install: True and two or more dependencies — it automatically installs when all its dependencies are present. For example, sale_stock is a glue module: it adds stock-related features to sale orders, but only makes sense when both sale and stock are installed.