Vue.js-style reactivity for Python. Wrap your state in a reactive proxy, and observ tracks every read and write for you: computed values invalidate themselves, watchers fire when something they depend on changes. No dirty flags, no manual invalidation, no dependency bookkeeping.
๐ Documentation ยท ๐ฆ PyPI ยท ๐งช Examples (Qt, rendercanvas)
Head straight to Collagraph โ a full-featured, Vue-inspired declarative UI framework built on top of observ. If you're looking for a strong reactive GUI framework for your Python Qt/PySide applications, Collagraph is the main entrypoint; observ is the reactivity engine underneath it.
- Automatic dependency tracking โ computed state knows exactly what it depends on and lazily re-evaluates only when needed.
- React to any change โ watch plain state or computed state and build unidirectional data flow: state changes drive view changes, input events drive state changes.
- Zero dependencies, framework agnostic โ a pure Python library (โฅ 3.13) that plugs into any event loop: asyncio, Qt, or your own.
- Fully typed โ a PEP 561 typed package, checked with ty in CI.
pip install observ
from observ import computed, reactive, watch
state = reactive({
"todos": [
{"title": "groceries", "done": False},
{"title": "dishes", "done": True},
],
})
@computed
def progress():
done = sum(todo["done"] for todo in state["todos"])
return f"{done}/{len(state['todos'])} done"
watcher = watch(progress, lambda new: print(new), sync=True)
# Mutate the plain dicts and lists you already have โ
# observ sees every change, no matter how deeply nested:
state["todos"][0]["done"] = True # prints: 2/2 done
state["todos"].append({"title": "laundry", "done": False}) # prints: 2/3 done
# ...but you only ever react when a *result* actually changes:
state["todos"][1]["title"] = "do the dishes" # (no print)No subclasses to inherit, no observable fields to declare, no signals to wire up: reactive() takes your existing data, and dependencies are tracked automatically simply by using it.
Continue with the Quick Start tutorial, or dive into the Guide and API Reference.
- Collagraph: reactive user interfaces in Python, built on top of observ.
- Reliev: the store (with undo/redo support) that used to be part of observ.
- Patchdiff: diffing and patching for plain Python data structures โ the same dicts, lists and sets you'd wrap with observ.