odoo/owl

OWL: A web framework for structured, dynamic and maintainable applications

TypeScript

1,595

1,981 commits

updated Oct 6, 2026

See the code

README

🦉 Owl 🦉

A modern, lightweight UI framework for applications that scale

License: LGPL v3 npm version Downloads


Owl 3.0.0 Alpha: This is an alpha release. The API and features are subject to change without notice.


Try it now

The fastest way to discover Owl is the online playground. It features interactive examples, a live editor, and showcases all major features: reactivity, components, plugins, and more. It also includes guided tutorials and is the recommended way to learn about Owl.

What is Owl?

Owl is a modern UI framework (~30kb gzipped, zero dependencies) written in TypeScript, built by Odoo. It powers Odoo's web client, one of the largest open-source business applications, but is equally suited for small projects and prototypes.

Key features:

  • Signal-based reactivity — Explicit, composable, and debuggable state management
  • Plugin system — Type-safe, composable sharing of state and services
  • Class-based components — Familiar OOP patterns with ES6 classes
  • Declarative templates — XML templates with a clean syntax
  • Async rendering — Concurrent mode for smooth user experiences

Quick Example

import { Component, signal, computed, mount, xml } from "@odoo/owl";

class TodoList extends Component {
  static template = xml`
    <input placeholder="Add todo..." t-on-keydown="this.onKeydown"/>
    <ul>
      <t t-foreach="this.todos()" t-as="todo" t-key="todo.id">
        <li t-att-class="{ done: todo.done }">
          <input type="checkbox" t-model="todo.done"/>
          <t t-out="todo.text"/>
        </li>
      </t>
    </ul>
    <p t-if="this.remaining() > 0">
      <t t-out="this.remaining()"/> item(s) remaining
    </p>`;

  todos = signal.Array([
    { id: 1, text: "Learn Owl", done: false },
    { id: 2, text: "Build something", done: false },
  ]);

  remaining = computed(() => this.todos().filter((t) => !t.done).length);

  onKeydown(ev) {
    if (ev.key === "Enter" && ev.target.value) {
      this.todos.push({
        id: Date.now(),
        text: ev.target.value,
        done: false,
      });
      ev.target.value = "";
    }
  }
}

mount(TodoList, document.body);

This example demonstrates Owl's reactivity: todos is a signal, remaining is a computed value that updates automatically, and the UI reacts to changes without manual subscription management.

Documentation

The full documentation is available at odoo.github.io/owl/documentation.

For the Owl 2 documentation, see the owl-2.x branch.

Installation

npm install @odoo/owl

Or download directly: latest release

Devtools

The Owl devtools extension helps debug your applications with component tree inspection, state visualization, and performance profiling. Download it from the releases page.

License

Owl is released under the LGPL v3 license.

odoo/owl

OWL: A web framework for structured, dynamic and maintainable applications

TypeScript

1,595

1,981 commits

updated Oct 6, 2026

See the code

README

🦉 Owl 🦉

A modern, lightweight UI framework for applications that scale

License: LGPL v3 npm version Downloads


Owl 3.0.0 Alpha: This is an alpha release. The API and features are subject to change without notice.


Try it now

The fastest way to discover Owl is the online playground. It features interactive examples, a live editor, and showcases all major features: reactivity, components, plugins, and more. It also includes guided tutorials and is the recommended way to learn about Owl.

What is Owl?

Owl is a modern UI framework (~30kb gzipped, zero dependencies) written in TypeScript, built by Odoo. It powers Odoo's web client, one of the largest open-source business applications, but is equally suited for small projects and prototypes.

Key features:

  • Signal-based reactivity — Explicit, composable, and debuggable state management
  • Plugin system — Type-safe, composable sharing of state and services
  • Class-based components — Familiar OOP patterns with ES6 classes
  • Declarative templates — XML templates with a clean syntax
  • Async rendering — Concurrent mode for smooth user experiences

Quick Example

import { Component, signal, computed, mount, xml } from "@odoo/owl";

class TodoList extends Component {
  static template = xml`
    <input placeholder="Add todo..." t-on-keydown="this.onKeydown"/>
    <ul>
      <t t-foreach="this.todos()" t-as="todo" t-key="todo.id">
        <li t-att-class="{ done: todo.done }">
          <input type="checkbox" t-model="todo.done"/>
          <t t-out="todo.text"/>
        </li>
      </t>
    </ul>
    <p t-if="this.remaining() > 0">
      <t t-out="this.remaining()"/> item(s) remaining
    </p>`;

  todos = signal.Array([
    { id: 1, text: "Learn Owl", done: false },
    { id: 2, text: "Build something", done: false },
  ]);

  remaining = computed(() => this.todos().filter((t) => !t.done).length);

  onKeydown(ev) {
    if (ev.key === "Enter" && ev.target.value) {
      this.todos.push({
        id: Date.now(),
        text: ev.target.value,
        done: false,
      });
      ev.target.value = "";
    }
  }
}

mount(TodoList, document.body);

This example demonstrates Owl's reactivity: todos is a signal, remaining is a computed value that updates automatically, and the UI reacts to changes without manual subscription management.

Documentation

The full documentation is available at odoo.github.io/owl/documentation.

For the Owl 2 documentation, see the owl-2.x branch.

Installation

npm install @odoo/owl

Or download directly: latest release

Devtools

The Owl devtools extension helps debug your applications with component tree inspection, state visualization, and performance profiling. Download it from the releases page.

License

Owl is released under the LGPL v3 license.

Project health

Overall

4.7/10

Maintained

10/10

Code review

8/10
OpenSSF Scorecard

Latest release

2.8.3 · Mar 30, 2026

Releases this year

2

Significant stargazers

Aiden Bai

5,830 followers · starred Dec 2023

Danny Willems

164 followers · starred Sep 2020

Jairo Llopis

189 followers · starred Oct 2019

Icebob

832 followers · starred Oct 2023