Way4Tech

Odoo OWL development, from nothing to production

OWL is the framework every screen in Odoo is built from. Learn it properly and the backend stops being something you configure around and becomes something you can change.

40 lessons, free, no sign up. Every lesson is written against a running Odoo and ships the code it describes. The faults in Part 7 are ones we hit on live systems, not ones invented to make a point.

What you need before you start

  • JavaScript to the level of classes, modules, promises and async/await. No framework experience is assumed.
  • An Odoo instance you can restart and break. A local Docker container is ideal; do not learn on anything a client uses.
  • Enough Python and Odoo to know what a model and a view are. You will not be asked to write much Python.

Part 1. Getting your bearings

What OWL is, why Odoo threw away the previous framework, and how to get code you have written onto a page you can see.

  1. 1 What OWL is, and why Odoo wrote its own framework Explain what OWL is, how it differs from the widget system it replaced, and why Odoo maintains its own framework.
  2. 2 A development setup where saving a file changes the page Run Odoo locally with a loop where saving a JavaScript or XML file shows up on reload, and diagnose it when it does not.
  3. 3 Asset bundles: how your JavaScript actually reaches the browser Put a file in the right bundle, control its load order, and know whether a change needs an upgrade or just a reload.
  4. 4 Your first OWL component, on a page you can actually see Write a working OWL component, register it so Odoo renders it, and read the console when it does not appear.

Part 2. Components

The unit everything else is built from: templates, props, events and the judgement about where one component should end.

  1. 5 The anatomy of an OWL component Write a component class with every part in the right place, and explain why setup() replaces the constructor.
  2. 6 QWeb templates in OWL: every directive you will use Write any OWL template, choose correctly between t-esc and t-out, and avoid the t-foreach key bug.
  3. 7 Props, and validating them so mistakes fail loudly Pass and validate props correctly, and recognise the two prop mistakes that cause most parent-child bugs.
  4. 8 Events: how a child talks back to a parent Handle DOM events, pass callbacks upward correctly, and recognise OWL 1 event code that no longer works.
  5. 9 Slots: components that take content Build a component whose content the parent supplies, including named slots and slots that pass data back.
  6. 10 Splitting a screen into components without making a mess Decide where a component should end, and extract shared behaviour into a hook instead of a base class.

Part 3. Reactivity

Why a screen redraws itself, the three ways people accidentally switch that off, and how to tell which one you have done.

  1. 11 useState, and what actually causes a re-render Explain exactly when OWL re-renders, and predict whether a given write will update the screen.
  2. 12 reactive(), and sharing state between components Build a shared reactive store and subscribe components to it correctly.
  3. 13 Derived values without a computed() helper Derive values correctly with getters, and use useEffect only where a getter cannot work.
  4. 14 Five reactivity bugs, and how to tell which one you have Diagnose a reactivity fault from its symptom in under a minute.

Part 4. The lifecycle

Every hook in the order it fires, what is safe to do inside each one, and the two that cause most of the bugs.

  1. 15 The whole OWL lifecycle on one page Name every lifecycle hook, say when it fires, and choose the right one for a given job.
  2. 16 onWillStart: loading data before anything renders Load data before first render safely, and decide when blocking the render is the wrong choice.
  3. 17 onMounted, refs, and working with the real DOM Safely touch the DOM from a component, and integrate a third party library that needs a real element.
  4. 18 onWillUpdateProps: reacting when the parent changes its mind Reload a component when its props change, without discarding user input or racing itself.
  5. 19 Cleanup and onError: not leaking, and not taking the screen down Clean up everything a component started, and contain a failure to the component that caused it.

Part 5. Services and registries

How a component reaches the server, opens a dialog or starts an action, and how Odoo finds code you added.

  1. 20 What a service is, and the ones you will use every day Explain what a service is, reach one from a component, and name the right service for a given job.
  2. 21 The ORM service: reading and writing records from OWL Query and modify Odoo records from a component, and call your own Python methods safely.
  3. 22 Notifications, dialogs and confirmation Show toasts and dialogs, including a dialog containing your own component.
  4. 23 The action service: opening views and navigating Open any view or action from a component, and react to what happens when it closes.
  5. 24 Registries: how Odoo finds the code you added Register anything in the right category, control its position, and inspect a registry live.
  6. 25 Writing your own service Write, register and use a service with dependencies and shared reactive state.

Part 6. Extending Odoo itself

Changing components you do not own, and adding field widgets, systray items, client actions and view types.

  1. 26 patch(): changing a component you do not own Patch a core component's behaviour and template without copying core code.
  2. 27 Writing a custom field widget Write, register and use a custom field widget, and extend a standard one.
  3. 28 A field widget with its own editing interface Build a field widget whose value is not a simple input, including one that reads related records.
  4. 29 Systray items, the user menu and the command palette Add a systray item with a dropdown, a user menu entry and a command palette action.
  5. 30 Client actions: a full screen of your own Build a client action with a proper control panel, reachable from a menu and from Python.
  6. 31 Extending a standard view Add behaviour to a standard view, scoped to the models you intend, without copying core code.
  7. 32 A view type of your own Build a custom view type end to end, and judge when not to.

Part 7. Making it hold up

Tests, debugging a minified bundle in production, performance, and writing code that survives the next version.

  1. 33 Testing OWL components with Hoot Write and run a Hoot test for a component, with a mocked server and mocked services.
  2. 34 Debugging a minified bundle in production Diagnose a client side fault on a system you cannot put into developer mode.
  3. 35 Performance: what actually costs you Find the real cost in a slow screen and fix it, instead of optimising rendering that was never the problem.
  4. 36 Writing OWL that survives the next Odoo version Write client code that is cheap to carry across versions, and upgrade a module methodically.
  5. 37 The faults that reach production Recognise the fault patterns that pass review and testing but fail on a real system.

Part 8. Three builds, end to end

A dashboard, a field widget and a complete module, each built from an empty folder with nothing skipped.

  1. 38 Build: a sales dashboard client action Build a production shaped dashboard, aggregated on the server and safe for non administrators.
  2. 39 Build: a colour and size grid field widget Build a field widget with a real editing interface that behaves correctly in form, list and readonly.
  3. 40 Build: a complete module, folder to shipped Assemble a complete, shippable module using every technique in this course.

Why this course exists

We build and sell Odoo modules, so we write OWL every week and we carry the cost when it goes wrong. Most OWL material online is a rewording of the source. This is written the other way round, from the faults that reached production and what they taught us.

If you would rather we built it, that is what we do.