Skip to main content

Observ 👁

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)

🖼️ Building a GUI?

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.

Why observ?

  • 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.

Quick start

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.

Metadata

Release files for observ 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for observ 1.0.1
File Size Uploaded
observ-1.0.1.tar.gz 69.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for observ 1.0.1
File Interpreter ABI Platform
observ-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 96.1 kB

Release files / observ-1.0.1.tar.gz

Download URL observ-1.0.1.tar.gz
Size 69.3 kB
Tags Source
SHA-256 checksum
How to use checksums
ee7129082c8e4b9199ba0133c5cd18c99f2b78930db1551f38336ee3dbaafac9
BLAKE2b-256 checksum
How to use checksums
bca1b48612c888e9f2f2bfa3f21ed4eed2dd676b8b15b847e0962b0ed315cd9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release files / observ-1.0.1-py3-none-any.whl

Download URL observ-1.0.1-py3-none-any.whl
Size 26.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5392f91ab1b6e1c94dc6aec28b5c372db7c0556d6a786e56595fa3574ece90c6
BLAKE2b-256 checksum
How to use checksums
66e054fa36f516ddfb949b323446b118312534ff3acd9b782a80166df2b7f8f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

0.18.0

2 release files

0.17.3

2 release files

0.17.2

2 release files

0.17.1

2 release files

0.17.0

2 release files

0.16.1

2 release files

0.16.0

2 release files

0.15.1

2 release files

0.14.1

2 release files

0.14.0

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.10.0

2 release files

0.9.5

2 release files

0.9.4

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page