Signal-based Reactivity
Explicit, composable, and debuggable state management. Read signals by calling them, making dependencies visible and bugs easier to trace.
Plugin System
Type-safe, composable sharing of state and services across components. Plugins replace the env pattern with something more powerful.
Class Components
Familiar OOP patterns with ES6 classes. Combine the readability of class-based architecture with modern reactivity.
XML Templates
Declarative templates with a clean syntax. Templates can be stored, modified dynamically, and targeted with xpaths.
Async Rendering
Concurrent mode for smooth user experiences. Components can load data asynchronously without blocking the UI.
No Toolchain Required
Works directly in the browser with native ES modules. No build step needed to get started.
Quick Example
import { Component, signal, mount, xml } from "@odoo/owl";
class Counter extends Component {
static template = xml`
<div class="counter">
<button t-on-click="this.decrement">-</button>
<span t-out="this.count()"/>
<button t-on-click="this.increment">+</button>
</div>`;
count = signal(0);
increment() { this.count.set(this.count() + 1); }
decrement() { this.count.set(this.count() - 1); }
}
mount(Counter, document.body);
Learn Owl
The playground includes guided tutorials — the best way to get started.