|
1 | | -<h1 align="center">🦉 <a href="https://odoo.github.io/owl/">Owl Framework</a> 🦉</h1> |
| 1 | +<h1 align="center">🦉 <a href="https://odoo.github.io/owl/">Owl</a> 🦉</h1> |
2 | 2 |
|
3 | | - [](https://www.gnu.org/licenses/lgpl-3.0) |
| 3 | +<p align="center"> |
| 4 | + <strong>A modern, lightweight UI framework for applications that scale</strong> |
| 5 | +</p> |
| 6 | + |
| 7 | +[](https://www.gnu.org/licenses/lgpl-3.0) |
4 | 8 | [](https://badge.fury.io/js/@odoo%2Fowl) |
5 | 9 | [](https://www.npmjs.com/package/@odoo/owl) |
6 | 10 |
|
7 | | -_Class based components with hooks, signals and concurrent mode_ |
| 11 | +--- |
8 | 12 |
|
9 | | -**Try it online!** you can experiment with the Owl framework in an online [playground](https://odoo.github.io/owl/playground). |
| 13 | +> **Owl 3.0.0 Alpha:** This is an alpha release. The API and features are subject to change without notice. |
10 | 14 |
|
11 | | -## Project Overview |
| 15 | +--- |
12 | 16 |
|
13 | | -The Odoo Web Library (Owl) is a smallish (~<20kb gzipped) UI framework built by |
14 | | -[Odoo](https://www.odoo.com/) for its products. Owl is a modern |
15 | | -framework, written in Typescript, taking the best ideas from React and Vue in a |
16 | | -simple and consistent way. Owl's main features are: |
| 17 | +## Try it now |
17 | 18 |
|
18 | | -- a declarative component system, |
19 | | -- a signal-based reactivity system (signals, computed values, effects), |
20 | | -- a plugin system for sharing state and services, |
21 | | -- hooks, |
22 | | -- fragments, |
23 | | -- asynchronous rendering |
| 19 | +The fastest way to discover Owl is the **[online playground](https://odoo.github.io/owl/playground)**. |
| 20 | +It features interactive examples, a live editor, and showcases all major features: |
| 21 | +reactivity, components, plugins, and more. It also includes **guided tutorials** |
| 22 | +and is the recommended way to learn about Owl. |
24 | 23 |
|
25 | | -Owl components are defined with ES6 classes and xml templates, uses an |
26 | | -underlying virtual DOM, integrates beautifully with hooks, and the rendering is |
27 | | -asynchronous. |
| 24 | +## What is Owl? |
28 | 25 |
|
29 | | -Quick links: |
| 26 | +Owl is a modern UI framework (~20kb gzipped, zero dependencies) written in TypeScript, |
| 27 | +built by [Odoo](https://www.odoo.com/). It powers Odoo's web client, one of the largest |
| 28 | +open-source business applications, but is equally suited for small projects and prototypes. |
30 | 29 |
|
31 | | -- [documentation](#documentation), |
32 | | -- [changelog](CHANGELOG.md) (from Owl 1.x to 2.x), |
33 | | -- [Owl 3.x release notes](release_notes.md) (draft), |
34 | | -- [playground](https://odoo.github.io/owl/playground) |
| 30 | +Key features: |
35 | 31 |
|
36 | | -## Example |
| 32 | +- **Signal-based reactivity** — Explicit, composable, and debuggable state management |
| 33 | +- **Plugin system** — Type-safe, composable sharing of state and services |
| 34 | +- **Class-based components** — Familiar OOP patterns with ES6 classes |
| 35 | +- **Declarative templates** — XML templates with a clean syntax |
| 36 | +- **Async rendering** — Concurrent mode for smooth user experiences |
37 | 37 |
|
38 | | -Here is a short example to illustrate interactive components: |
| 38 | +## Quick Example |
39 | 39 |
|
40 | 40 | ```javascript |
41 | | -const { Component, signal, mount, xml } = owl; |
| 41 | +import { Component, signal, computed, mount, xml } from "@odoo/owl"; |
42 | 42 |
|
43 | | -class Counter extends Component { |
| 43 | +class TodoList extends Component { |
44 | 44 | static template = xml` |
45 | | - <button t-on-click="this.increment"> |
46 | | - Click Me! [<t t-out="this.count()"/>] |
47 | | - </button>`; |
48 | | - |
49 | | - count = signal(0); |
50 | | - |
51 | | - increment() { |
52 | | - this.count.set(this.count() + 1); |
| 45 | + <input placeholder="Add todo..." t-on-keydown="this.onKeydown"/> |
| 46 | + <ul> |
| 47 | + <t t-foreach="this.todos()" t-as="todo" t-key="todo.id"> |
| 48 | + <li t-att-class="{ done: todo.done }"> |
| 49 | + <input type="checkbox" t-model="todo.done"/> |
| 50 | + <t t-out="todo.text"/> |
| 51 | + </li> |
| 52 | + </t> |
| 53 | + </ul> |
| 54 | + <p t-if="this.remaining() > 0"> |
| 55 | + <t t-out="this.remaining()"/> item(s) remaining |
| 56 | + </p>`; |
| 57 | + |
| 58 | + todos = signal.Array([ |
| 59 | + { id: 1, text: "Learn Owl", done: false }, |
| 60 | + { id: 2, text: "Build something", done: false }, |
| 61 | + ]); |
| 62 | + |
| 63 | + remaining = computed(() => this.todos().filter((t) => !t.done).length); |
| 64 | + |
| 65 | + onKeydown(ev) { |
| 66 | + if (ev.key === "Enter" && ev.target.value) { |
| 67 | + this.todos.push({ |
| 68 | + id: Date.now(), |
| 69 | + text: ev.target.value, |
| 70 | + done: false, |
| 71 | + }); |
| 72 | + ev.target.value = ""; |
| 73 | + } |
53 | 74 | } |
54 | 75 | } |
55 | 76 |
|
56 | | -class Root extends Component { |
57 | | - static template = xml` |
58 | | - <span>Hello Owl</span> |
59 | | - <Counter/>`; |
| 77 | +mount(TodoList, document.body); |
| 78 | +``` |
60 | 79 |
|
61 | | - static components = { Counter }; |
62 | | -} |
| 80 | +This example demonstrates Owl's reactivity: `todos` is a signal, `remaining` |
| 81 | +is a computed value that updates automatically, and the UI reacts to changes |
| 82 | +without manual subscription management. |
63 | 83 |
|
64 | | -mount(Root, document.body); |
65 | | -``` |
| 84 | +## Design Principles |
| 85 | + |
| 86 | +Owl is built on principles that make it powerful yet approachable: |
66 | 87 |
|
67 | | -Note that the counter component is made reactive with a [`signal`](release_notes.md#signals). |
68 | | -Also, all examples here use the `xml` helper to define inline templates. |
69 | | -But this is not mandatory, many applications will load templates separately. |
| 88 | +**Explicit over Implicit** |
70 | 89 |
|
71 | | -More interesting examples can be found on the |
72 | | -[playground](https://odoo.github.io/owl/playground) application. |
| 90 | +Reactiveness is explicit — you read signals by calling them (`this.count()`), |
| 91 | +making dependencies visible and bugs easier to trace. No hidden magic. |
73 | 92 |
|
74 | | -## Documentation |
| 93 | +**Composable Architecture** |
75 | 94 |
|
76 | | -Note: the reference documentation below was written for Owl 2.x. The |
77 | | -[Owl 3.x release notes](release_notes.md) describe all changes in detail. |
| 95 | +Plugins provide a structured way to share state and services across components. |
| 96 | +They compose naturally and support full type inference. |
78 | 97 |
|
79 | | -### Learning Owl |
| 98 | +**Scales with You** |
80 | 99 |
|
81 | | -Are you new to Owl? This is the place to start! |
| 100 | +Start simple with inline templates and signals. Grow into a large codebase |
| 101 | +with external templates, registries, and plugins. Owl powers Odoo's |
| 102 | +multi-million-line codebase — it's proven at scale. |
82 | 103 |
|
83 | | -- [Tutorial: create a TodoList application](doc/learning/tutorial_todoapp.md) |
84 | | -- [How to start an Owl project](doc/learning/quick_start.md) |
85 | | -- [How to test Components](doc/learning/how_to_test.md) |
| 104 | +**Developer Experience** |
86 | 105 |
|
87 | | -### Reference |
| 106 | +First-class TypeScript support, comprehensive error messages in dev mode, |
| 107 | +and a browser devtools extension for debugging. |
| 108 | + |
| 109 | +## Resources |
| 110 | + |
| 111 | +### Getting Started |
| 112 | + |
| 113 | +- **[Playground](https://odoo.github.io/owl/playground)** — Interactive examples and live coding |
| 114 | +- **[Owl 3.x Release Notes](release_notes.md)** — Complete guide to all changes |
| 115 | +- [Tutorial: Getting Started](https://odoo.github.io/owl/playground#getting_started) — Learn Owl fundamentals step by step |
| 116 | +- [Tutorial: Todo List](https://odoo.github.io/owl/playground#todo_list) — Build a full TodoMVC app |
| 117 | +- [Tutorial: Hibou OS](https://odoo.github.io/owl/playground#hibou_os) — Build a desktop-like interface |
| 118 | + |
| 119 | +### Reference Documentation |
88 | 120 |
|
89 | 121 | - [Overview](doc/readme.md) |
90 | | -- [App](doc/reference/app.md) |
91 | | -- [Component](doc/reference/component.md) |
92 | | -- [Component Lifecycle](doc/reference/component.md#lifecycle) |
93 | | -- [Concurrency Model](doc/reference/concurrency_model.md) |
94 | | -- [Dev mode](doc/reference/app.md#dev-mode) |
95 | | -- [Dynamic sub components](doc/reference/component.md#dynamic-sub-components) |
96 | | -- [Error Handling](doc/reference/error_handling.md) |
97 | | -- [Event Handling](doc/reference/event_handling.md) |
98 | | -- [Form Input Bindings](doc/reference/input_bindings.md) |
99 | | -- [Fragments](doc/reference/templates.md#fragments) |
100 | | -- [Hooks](doc/reference/hooks.md) |
101 | | -- [Loading Templates](doc/reference/app.md#loading-templates) |
102 | | -- [Mounting a component](doc/reference/app.md#mount-helper) |
103 | | -- [Precompiling templates](doc/reference/precompiling_templates.md) |
104 | | -- [Props](doc/reference/props.md) |
105 | | -- [Props Validation](doc/reference/props.md#props-validation) |
106 | | -- [Reactivity](doc/reference/reactivity.md) |
107 | | -- [Rendering SVG](doc/reference/templates.md#rendering-svg) |
108 | | -- [Refs](doc/reference/refs.md) |
| 122 | +- [App](doc/reference/app.md) | [Component](doc/reference/component.md) |
| 123 | +- [Reactivity](doc/reference/reactivity.md) | [Hooks](doc/reference/hooks.md) |
| 124 | +- [Templates](doc/reference/templates.md) | [Props](doc/reference/props.md) |
109 | 125 | - [Slots](doc/reference/slots.md) |
110 | | -- [Sub components](doc/reference/component.md#sub-components) |
111 | | -- [Sub templates](doc/reference/templates.md#sub-templates) |
112 | | -- [Templates (Qweb)](doc/reference/templates.md) |
113 | | -- [Translations](doc/reference/translations.md) |
114 | | -- [Utils](doc/reference/utils.md) |
115 | 126 |
|
116 | | -### Other Topics |
| 127 | +### Understanding Owl |
117 | 128 |
|
118 | | -- [Notes On Owl Architecture](doc/miscellaneous/architecture.md) |
| 129 | +- [Why we built Owl](doc/miscellaneous/why_owl.md) |
| 130 | +- [Architecture Notes](doc/miscellaneous/architecture.md) |
119 | 131 | - [Comparison with React/Vue](doc/miscellaneous/comparison.md) |
120 | | -- [Why did Odoo build Owl?](doc/miscellaneous/why_owl.md) |
121 | | -- [Changelog (from owl 1.x to 2.x)](CHANGELOG.md) |
122 | | -- [Owl 3.x Release Notes (draft)](release_notes.md) |
123 | | -- [Notes on compiled templates](doc/miscellaneous/compiled_template.md) |
124 | | -- [Owl devtools extension](doc/tools/devtools.md) |
125 | 132 |
|
126 | | -## Installing Owl |
| 133 | +## Installation |
127 | 134 |
|
128 | | -Owl is available on `npm` and can be installed with the following command: |
129 | | - |
130 | | -``` |
| 135 | +```bash |
131 | 136 | npm install @odoo/owl |
132 | 137 | ``` |
133 | | -If you want to use a simple `<script>` tag, the last release can be downloaded here: |
134 | | - |
135 | | -- [owl](https://github.com/odoo/owl/releases/latest) |
136 | | - |
137 | | -## Installing Owl devtools |
138 | 138 |
|
139 | | -The Owl devtools browser extension is also available in the [release](https://github.com/odoo/owl/releases/latest): |
140 | | -Unzip the owl-devtools.zip file and follow the instructions depending on your browser: |
| 139 | +Or download directly: [latest release](https://github.com/odoo/owl/releases/latest) |
141 | 140 |
|
142 | | -### Chrome |
| 141 | +## Devtools |
143 | 142 |
|
144 | | -Go to your chrome extensions admin panel, activate developer mode and click on `Load unpacked`. |
145 | | -Select the devtools-chrome folder and that's it, your extension is active! |
146 | | -There is a convenient refresh button on the extension card (still on the same admin page) to update your code. |
147 | | -Do note that if you have problems, you may need to completely remove and reload the extension to fully refresh it. |
| 143 | +The Owl devtools extension helps debug your applications with component tree |
| 144 | +inspection, state visualization, and performance profiling. Download it from |
| 145 | +the [releases page](https://github.com/odoo/owl/releases/latest). |
148 | 146 |
|
149 | | -### Firefox |
150 | | -Go to the address about:debugging#/runtime/this-firefox and click on `Load temporary Add-on...`. |
151 | | -Select any file in the devtools-firefox folder and that's it, your extension is active! |
152 | | -Here, you can use the reload button to refresh the extension. |
| 147 | +## License |
153 | 148 |
|
154 | | -Note that you may have to open another window or reload your tab to see the extension working. |
155 | | -Also note that the extension will only be active on pages that have a sufficient version of owl. |
| 149 | +Owl is released under the [LGPL v3](https://www.gnu.org/licenses/lgpl-3.0) license. |
0 commit comments