Skip to content

CLAUDE.md for Odoo Projects: The Ultimate Setup Guide

DeployMonkey Team · March 22, 2026 11 min read

What Is CLAUDE.md?

CLAUDE.md is a project-level context file that tells Claude Code about your development environment, coding conventions, and project-specific details. For Odoo development, it is the single most important file you can create — it determines whether Claude generates code for the correct Odoo version with the right patterns.

Without CLAUDE.md, Claude Code uses its general training data, which mixes patterns from Odoo 14 through 19. With it, Claude generates version-correct code consistently.

The Complete Template

# CLAUDE.md — Odoo Module Development

## Environment
- Odoo version: 19.0  # CHANGE THIS to your version
- Python: 3.12
- PostgreSQL: 16
- Edition: Community  # or Enterprise
- Dev database: myproject_dev

## Module Structure
- Custom addons path: /custom/addons/
- Module structure follows standard Odoo:
  __manifest__.py, __init__.py, models/, views/, security/, data/,
  static/, controllers/, wizards/, tests/

## Version-Specific Rules (Odoo 19)
- ORM imports: `from odoo import api, fields, models` (unchanged)
- Views: use `<list>` NOT `<tree>` (changed in v18)
- No `attrs=` in XML views (removed in v17)
  Use: invisible="condition" readonly="condition" required="condition"
- Constraints: use `models.Constraint("UNIQUE(field)", "message")`
  NOT `_sql_constraints`
- Indexes: use `models.Index("index_name", "field1", "field2")`
- Domains: can use Domain class or traditional list format
- Date defaults: `fields.Date.today` not `datetime.now().date()`

## Coding Conventions
- Model names: dot-separated (project.milestone)
- Table names: auto-generated from model name
- Field names: snake_case
- Method names: snake_case, private methods prefixed with _
- Always add _description to models
- Always add `string=` to fields for clarity
- Use `@api.depends` for computed fields
- Use `@api.constrains` for validation
- Use `@api.onchange` sparingly (prefer computed fields)

## Security
- Always create security/ir.model.access.csv
- Include both user (read) and admin (full) access lines
- For multi-company: add record rules with company_id domain
- NEVER use `sudo()` unless absolutely necessary

## Views
- Form views: use <sheet>, <group>, <notebook> structure
- List views: use optional="show/hide" for non-essential columns
- Search views: add useful default filters and group-by options
- Menus: add to appropriate parent menu, not root

## Testing
- Test file: tests/test_module_name.py
- Import in tests/__init__.py
- Use TransactionCase for model tests
- Use HttpCase for controller tests
- Run: python odoo-bin -d testdb --test-tags /module_name

## Don'ts
- Don't use `@api.one` (removed in v13)
- Don't use `@api.multi` (removed in v13)
- Don't use `@api.returns` (deprecated)
- Don't use `name_get()` override (deprecated in v17, use _rec_name)
- Don't use `_columns` or `_defaults` (ancient API)
- Don't hardcode IDs — use XML IDs with `self.env.ref()`
- Don't use `cr.execute()` for queries that ORM can handle

Version-Specific Templates

Odoo 17 Differences

# Additional rules for Odoo 17:
# - attrs= REMOVED from XML views
#   OLD: attrs="{'invisible': [('state', '!=', 'draft')]}"
#   NEW: invisible="state != 'draft'"
# - name_get() deprecated — use _rec_name or display_name compute
# - _read_group() signature changed
# - <tree> still used (NOT yet renamed to <list>)
# - Use _sql_constraints (Constraint class not yet available)

Odoo 18 Differences

# Additional rules for Odoo 18:
# - <tree> renamed to <list> (BREAKING)
# - Hoot testing replaces QUnit for JS tests
# - @api.readonly decorator introduced
# - Bootstrap 5.3.3
# - aggregator field attribute replaces group_operator
# - No attrs= (removed in v17)
# - Use _sql_constraints (Constraint class not yet available)

Odoo 16 Differences

# Additional rules for Odoo 16:
# - attrs= STILL USED (not removed until v17)
# - <tree> STILL USED (not renamed until v18)
# - WebSocket introduced (replaces long polling)
# - Json/Properties fields introduced
# - Translation system overhauled (_() usage changes)
# - flush_model/invalidate_model APIs introduced
# - Use _sql_constraints

Adding Knowledge Base Context

For the best results, reference your Odoo knowledge base files:

# Knowledge Base
Version-specific documentation is available in:
- /knowledge_base/odoo-19.0/community/ (21 files, 6439 lines)
- /knowledge_base/odoo-19.0/enterprise/ (9 files, 3173 lines)

Key references:
- ORM API: 01_orm_api.md
- Fields: 02_fields.md
- Views: 03_views_xml.md
- Security: 04_security.md
- Inheritance: 06_inheritance.md
- Testing: 12_testing.md
- Common patterns: 14_common_patterns.md
- Anti-patterns: 15_anti_patterns.md

Project-Specific Additions

Customize the template with your project's specifics:

# Project-Specific
- This module extends: sale, stock, account
- Custom fields added to res.partner: x_credit_score, x_tier
- Multi-company: all models must have company_id
- Naming convention: all custom fields prefixed with x_
- All controllers use auth='user' unless explicitly public
- Email templates go in data/email_templates.xml

Verifying Your CLAUDE.md Works

After creating CLAUDE.md, test it with a simple prompt:

"Create a model called project.milestone with fields: name (required), deadline (date), project_id (many2one to project.project), status (selection: draft/in_progress/done). Add form and list views."

Check the output for:

  • Correct view tag (<list> for v18+, <tree> for v17 and below)
  • No attrs= in views (v17+)
  • Correct constraint syntax for your version
  • Proper security CSV format
  • Correct __manifest__.py structure

Getting Started

Copy the template above, change the Odoo version to match yours, add your project-specific conventions, and save as CLAUDE.md in your project root. This 5-minute setup pays for itself on the first module you generate. Deploy the generated modules to DeployMonkey with Git integration for instant testing.