diff --git a/README.md b/README.md
index 1022b576..e72c91e5 100644
--- a/README.md
+++ b/README.md
@@ -74,6 +74,7 @@ Are you new to Owl? This is the place to start!
- [Tutorial: create a TodoList application](doc/learning/tutorial_todoapp.md)
- [How to start an Owl project](doc/learning/quick_start.md)
- [How to test Components](doc/learning/how_to_test.md)
+- [How to organize Owl code](doc/miscellaneous/organizing_code.md)
### Reference
diff --git a/doc/miscellaneous/organizing_code.md b/doc/miscellaneous/organizing_code.md
new file mode 100644
index 00000000..05926bae
--- /dev/null
+++ b/doc/miscellaneous/organizing_code.md
@@ -0,0 +1,380 @@
+# 🦉 Organising Owl code 🦉
+
+## Content
+
+- [Overview](#overview)
+- [Reactivity](#reactivity)
+- [Asynchrony](#asynchrony)
+- [Basic design: Components and Props](#basic-design-components-and-props)
+- [More advanced design: using the environment](#more-advanced-design-using-the-environment)
+- [Even more advanced: completely separating model management](#even-more-advanced-completely-separating-model-management)
+- [Special case: bypassing reactivity](#special-case-bypassing-reactivity)
+
+## Overview
+
+The topic of this document is to discuss how one could organize an Owl
+application/component/feature/codebase. Clearly, good practices for a system depends
+on its properties/semantics. For Owl 2.x applications, the most important
+ideas to have in mind are the following:
+
+- Owl provides a way to structure a component tree,
+- communication between a parent and a child component is mostly done with props
+ (and callback props to go from child to parent),
+- there is an additional communication channel: information can be propagated
+ through the environment,
+- Owl implements a reactivity system, which tracks each components and values,
+ so that it is able to only rerender the relevant subset of components,
+- asynchrony: owl components can delay renderings with `onWillStart`/`onWillUpdateProps`
+- renderings are batched (10 calls to render in the same call stack will only
+ result in 1 actual rendering)
+
+## Reactivity
+
+With the reactivity system, each value created with the `useState` or the `reactive`
+function is a proxy that allows Owl to trask which keys/values have been read
+by which components. This means that Owl can then only update the components that
+are impacted by a state change.
+
+There are two important reactivity primitives:
+
+- `useState`: a hook to turn a value into a reactive value, linked to a component
+ (so, each time the value is updated, the component is rerendered)
+- `reactive`: a function to create a "standalone" reactive value
+
+Also, it is good to know that one can call `useState` on a reactive value: this will
+create another reactive value, connected to the same source, but linked to a
+different component.
+
+Let us consider the following component tree:
+
+```mermaid
+graph TD
+ A-->B
+ A-->C
+ B-->D
+ B-->E
+ B-->F
+ C-->G
+ C-->H
+```
+
+It is important to know how renderings are applied by Owl:
+
+- if a render is initiated in A, it will render its template
+- whenever it encounter a child component (here, B and C), it will shallow
+ compare the before and after props. If they are different, Owl will render the
+ corresponding child component, otherwise it will stop.
+- each props object received by a (child) component is turned into a reactive
+ object.
+
+Each (non primitive) value given by `A` to `B` and `C` will be transformed into
+a reactive object.
+basically, owl does a useState on props at each level, and compare
+shallowly values
+
+Notes:
+
+- each component can be independently rendered (so, for example, only B and D)
+- one can create reactive objects (just like useState, but not linked to any
+ component) with the `reactive` function
+- escape hatch: one can mark an object as "raw" (non reactive) with `markRaw`, and get the target
+ object (with `toRaw`)
+- note that it is bad practice to keep reference to the raw object: doing so means
+ that some => may miss
+ rendering
+
+- note: reactivity is not free. It may be expensive for some large objects.
+
+## Asynchrony
+
+explain: onWillStart and onWillUpdateProps are async => can delay render
+
+good usecase for lazyloading libs
+
+note: most of the time, update should be done in an atomic way:
+
+```js
+// bad => will cause extra rendering, possibly corrupt
+this.state.something = someValue;
+const otherValue = await this.fetchSomething();
+this.state.otherValue = otherValue;
+```
+
+```js
+// good
+const otherValue = await this.fetchSomething();
+this.state.something = someValue;
+this.state.otherValue = otherValue;
+```
+
+```js
+// bad => will cause extra rendering, possibly corrupt
+const someValue = getsomeValue();
+const otherValue = await this.fetchSomething();
+Object.assign(this.state, {
+ someValue,
+ otherValue,
+});
+```
+
+other note: minimize async stuff
+
+```js
+setup() {
+ // strategy 1: have a loading screen
+ this.state = useState({loading: true});
+}
+```
+
+```xml
+
+
+...
+```
+
+// other strategy: not display a loading indicator, and update the UI atomically
+
+```js
+setup() {
+ onWillStart(() => this.loadData());
+ onWillUpdateProps(() => this.updateData());
+}
+```
+
+## Baseline design: Components and props
+
+Here is what I suppose many Owl systems will look like: `useState` in some components,
+state is propagated down the tree with props, and potentially callbacks as well
+(to communicate from child to parent)
+
+ A
+
+/ \
+ B C
+/ | \ | \
+D E F G H
+
+```js
+// in A (and maybe some/all other components)
+this.state = useState(...);
+```
+
+```xml
+
+
+
+
+
+
+
+```
+
+Notice the `.bind` suffix here, very convenient.
+
+```xml
+
+
+```
+
+With reactivity, any update to the state will only rerender the affected components.
+So, if some code in `A` update the value of `some_field` (without reading it!),
+only B will be rerendered.
+
+## More advanced design: passing stuff through the environment
+
+It may be tedious/impractical to pass props all along the tree when we have a deep
+component tree.
+
+One can then use the environment to communicate to children. Only issue with that
+is that stuff in the environment bypass the reactivity system: if it comes from
+a `useState` in `A` => only `A` will react to state changes, not the children that
+reads it.
+
+To solve that, one need to use `useState` on it:
+
+```js
+// in root component A
+class A extends Component {
+ setup() {
+ this.posModel = {
+ state: useState(this.state),
+ updateSomeValue: () => this.updateSomeValue(),
+ doSomethingElse: () => this.doSomethingElse(),
+ };
+ useSubEnv({ posModel: this.posModel });
+ }
+}
+
+// in some child component D
+class D extends Component {
+ setup() {
+ // this one is wrong! this.posModel.state is stated
+ this.posModel = this.env.posModel;
+
+ // this.posModel.state === the one in A, linked to the component A
+
+ // this one is ok!
+ this.posModel = useState(this.env.posModel);
+ }
+}
+```
+
+Note that we can slightly simplify the use of the model by a hook:
+
+```js
+function usePosModel() {
+ const env = useEnv();
+ const model = env.posModel;
+ return useState(model);
+}
+```
+
+This is not much simpler, but it makes sure that one does not forget to call
+`useState` on the model from the environment.
+
+## Even more advanced: completely separating model management
+
+The baseline design above it nice for many usecases, but we sometimes may want
+to separate the "model" management from the UI, especially as the model is doing
+more complicated stuff. Useful to code some complex transitions.
+
+Here is how we could use the environment and reactive object to organize code:
+
+```js
+// in my_model.js
+class MyModel {
+ ...
+ constructor() {
+ this.complicatedCacheObject = {};
+
+ markRaw(this.complicatedCacheObject);
+ }
+
+ async load(...) {
+
+ }
+
+ async update(...) {
+
+ }
+
+ async doSomeComplexThing() {
+ this.loading = true;
+
+ // coordinate here some thing
+ // fetch stuff...
+
+ this.loading = false;
+ this.data = ...;
+ ...
+ }
+ ...
+}
+
+// in root component A:
+
+class A extends Component {
+ setup() {
+ const model = useState(new MyModel(...));
+ useSubEnv({ model });
+ }
+}
+
+// in some child component:
+class D extends Component {
+ setup() {
+ // notice the useState: this is necessary to bind model changes to the
+ // component D
+ this.model = useState(this.env.model);
+ }
+}
+
+```
+
+Notes:
+
+- model could be created elsewhere, in a service, in the start code, ...
+- one may want to mark some internal stuff as 'raw'...
+- if created elsewhere, it should probably be done with `reactive`
+- the call to `reactive` could be done in the model constructor directly:
+
+ ```js
+ class MyModel {
+ constructor() {
+ ...
+ return reactive(this);
+ }
+ }
+ ```
+
+- one could slightly simplify the model use with a hook:
+
+```js
+function useModel() {
+ const env = useEnv();
+ const model = env.model;
+ return useState(model);
+}
+```
+
+This can be simply used like this in a child component:
+
+```js
+setup() {
+ this.model = useModel();
+}
+```
+
+## Special case: bypassing reactivity
+
+Sometimes, reactivity is not what we want. For example, the o_spreadsheet
+library has a huge extremely complex model, and each state transition may
+potentially update the full UI, so it needs to be fast anyway, and reactivity
+has a cost that may outweight the benefits.
+
+The strategy here is:
+
+- mark the model as raw (not necessary in all cases, but potentially important
+ if model is passed through some props)
+- find a way to be notified on update change (for example, by an event triggered
+ by an event bus)
+- perform a deep rendering: render(true), at the root component.
+
+Here is how one could organize the code then:
+
+```js
+class MainModel extends EventBus{
+ constructor() {
+ markRaw(this); // make sure this object will never be turned into a reactive
+ }
+
+ doSomething() {
+ ...
+ // need to notify the outside world that a change occurred
+ this.trigger("UPDATE");
+ }
+ ...
+}
+
+// in root component:
+class A extends Component {
+ setup() {
+ const model = new MainModel();
+
+ // notice the 'render(true)', to do a deep render
+ model.addEventListener("UPDATE", () => this.render(true));
+ useSubEnv({ model });
+ }
+}
+
+// in child components:
+class E extends Component {
+ setup() {
+ this.model = this.env.model; // not really necessary, but maybe nice
+ }
+
+ onClick() {
+ this.model.doSomething();
+ }
+}
+```