A hierarchical, lifecycle-aware MVVM viewmodel framework — one language-neutral
specification with five idiomatic source flavors (C# / Python / TypeScript /
Swift / Rust). All five source flavors cover the 396 library conformance IDs;
the flagship example apps cover 5 additional THEME scenario IDs for 401
total tracked scenarios. Catalog coverage is not a claim of member-for-member
surface parity: the remaining Rust convergence backlog is tracked in
docs/maintenance/2026-07-16-rust-capability-parity.md.
- Overview
- Architecture
- 2.1 Architecture diagram
- 2.2 Class diagram
- 2.3 Layers
- Flavors
- Getting started
- 4.1 Install
- 4.2 Quickstart guides
- 4.3 Examples
- Repository layout
- Versioning and conformance
- 6.1 SemVer policy
- 6.2 Conformance catalog
- Contributing
- License
VMx is a framework for building MVVM viewmodels with explicit lifecycle and reactive messaging. It targets WPF / Avalonia / MAUI on .NET, Tkinter / PyQt / NiceGUI / Textual on Python, and any DOM- or rxjs-based UI on TypeScript — but makes no assumption about the UI layer. Every flavor exposes:
- A five-state construction lifecycle (
Destructed,Constructing,Constructed,Destructing, plus terminalDisposed) with reversibleconstruct/destruct,reconstruct(), and a synchronous depth-firstdispose()cascade that can be invoked from any state. - A reactive message hub for
PropertyChangedMessageandConstructionStatusChangedMessage, plus collection-change events on container VMs. - Four hierarchy primitives — leaf
ComponentVM, selectableCompositeVM, peerGroupVM, fixed-arityAggregateVM1..6— plus forwarding decorators for instrumentation. - One shared VM collection capability for groups and composites, with selection layered only onto composites and atomic identity-preserving move.
- A
RelayCommandwith reactivecanExecutetriggers and explicit imperative re-evaluation notifications, plus v2.0 decorators (CompositeCommand,DecoratorCommand,ConfirmationDecoratorCommand) and a modeled-CRUD helper (ModeledCrudCommands). - Tree utilities (
walk,find,walk_expanded) for introspection. - 22 opt-in capability micro-interfaces (
ISelectable,IExpandable,IClosable,IFilterable,IPageable, …) and helper state classes (ExpandableState,SearchableState) for layering behaviour onto VMs additively.SearchableStateoptionally observes a source-change signal so an unchanged term stays synchronized with collection/member invalidations. DerivedProperty<T>for N-source computed values,FormVM<T>for snapshot/revert/validation flows,DiscriminatorVMfor single-active-key coordination,AsyncResourceVM<T>for cancellable latest-wins acquisition,PagedComposition/TokenPagedCompositionfor finite and cursor paging, an opt-in notification sub-package (INotificationHub),IDialogService, null-object service variants (NullMessageHub,NullDispatcher,NullNotificationHub,NullLocalizer,NullDialogService), and anILocalizerhook for i18n.
The normative conceptual shape is shared across flavors; public source surfaces still have the explicitly tracked Rust convergence gaps above. Naming follows the local idiom (PascalCase in C#, snake_case in Python and Rust, camelCase in TypeScript and Swift — codified in ADR-0006).
The rendered SVG is at assets/architecture.svg. A
browsable HTML version with summary cards is at
assets/architecture.html, and a high-resolution
PNG export is at assets/architecture.png.
A cluster-level map of the principal library families and their relationships.
The rendered SVG is at assets/class-diagram.svg. A
browsable HTML version with summary cards is at
assets/class-diagram.html, and a high-resolution
PNG export is at assets/class-diagram.png.
ComponentVM, the container families, and AsyncResourceVM participate in
the lifecycle base contract; Rust expresses relevant relationships through
component composition. FormVM, DiscriminatorVM, NotificationVM, and
ConfirmationVM are independent coordinators in the object-oriented flavors,
with Rust's FormVM composing a component leaf. The remaining clusters cover
commands, capabilities, services, messages, builders, collections, paging,
state helpers, and tree utilities. The exhaustive member contracts live in the
linked spec chapters and ADRs.
Each flavor implements the same conceptual stack:
- Spec —
spec/is the source of truth: 24 markdown chapters, 124 ADRs, 4 JSON fixtures, 401 conformance IDs, version pinned inspec/VERSION. - Application code — your host app instantiates VMs through builders.
- Forwarding decorators (optional) —
ForwardingComponentVMandForwardingCompositeVMwrap an inner VM for instrumentation, selective override, or composition. - Viewmodel hierarchy —
ComponentVM<M>,CompositeVM<VM>,GroupVM<VM>,AggregateVM1..6. - Commands —
RelayCommandandRelayCommand<T>withexecute,canExecute, reactive trigger observables, and imperative re-evaluation notifications. - Messages and collection events —
PropertyChangedMessage,ConstructionStatusChangedMessage,CollectionChangedEventwithBatchUpdate(), atomicMove, andAutoConstructOnAddoptions. - Tree utilities —
walk(root),walk_expanded(root), andfind(root, predicate)over any VM hierarchy. - Services —
MessageHub(hot-stream pub/sub) andRxDispatcher(paired foreground / background schedulers). - Lifecycle state machine — orchestrates every VM; transitions enforced
by a fixture-backed validator (
spec/fixtures/lifecycle-transitions.json). - Builders — immutable fluent setters that return new instances and
validate required fields on
build().
| Flavor | Source status | Public package status | Reactive primitive |
|---|---|---|---|
| C# | v3.22.0 in source | NuGet package not published yet | System.Reactive |
| Python | v3.22.0 in source | vmx latest published: 3.1.0 |
reactivex |
| TypeScript | v3.23.0 in source | npm package not published yet | rxjs |
| Swift | v3.22.0 in source | VMx 3.20.0 via SwiftPM |
Combine |
| Rust | v0.25.0 in source | crates.io package not published yet | VMx-owned hot-stream facade |
main may contain an in-development source version before that version is
published to package registries. The §3.2 summary preserves source-line parity
history, including lines that were never published. The
compatibility-matrix.md ledger is canonical for
released compatibility plus the current in-development line; use each registry
for installable package availability.
All five source flavors implement the 396 library conformance IDs. The flagship
example apps cover 5 additional THEME scenario IDs, for 401 total tracked
scenarios. Swift covers those UI scenarios through
examples/swift/notes-showcase/ (ADR-0067). See
langs/swift/README.md §5 for the Swift ID matrix.
The C# flavor multi-targets netstandard2.0 and
net8.0 and ships two companion assemblies:
VMx.Extensions.DependencyInjection (services.AddVMx(...)) and
VMx.Notifications (opt-in INotificationHub). Their NuGet pages will become
available with their first publication. The Python flavor supports Python 3.10 through 3.14,
is mypy --strict clean, and exposes vmx.notifications as an opt-in
subpackage. The TypeScript flavor (npm package @thekaveh/vmx — renamed
in v2.4.0 because the unscoped vmx name was unavailable) retains a Node 20
compatibility floor and tests Node 20, 22, 24, and 26. It emits dual ESM + CJS
bundles and exposes notifications plus an isolated
consumer-conformance tooling subpath. The Rust flavor lives under
langs/rust/ as the
vmx-rs crate with the vmx import namespace; it has full library conformance
coverage in source and is awaiting a crates.io release channel.
This summary preserves source-line history; a historical row does not by itself claim that packages or tags were published. See the canonical compatibility ledger linked above for release status and the current in-development line.
| spec | csharp | python | typescript | swift | rust |
|---|---|---|---|---|---|
| 3.22.x | 3.22.0 | 3.22.0 | 3.23.0 | 3.22.0 | 0.25.0 |
| 3.20.x | 3.20.0–3.20.1 | 3.20.0–3.20.1 | 3.20.0–3.21.1 | 3.20.0–3.20.1 | 0.20.0–0.22.0 |
| 3.19.x | 3.19.0 | 3.19.0 | 3.19.0 | 3.19.0 | 0.19.0 |
| 3.18.x | 3.18.0 | 3.18.0 | 3.18.0 | 3.18.0 | 0.18.0 |
| 3.17.x | 3.17.0 | 3.17.0 | 3.17.0 | 3.17.0 | 0.17.0 |
| 3.16.x | 3.16.0 | 3.16.0 | 3.16.0 | 3.16.0 | 0.16.0 |
| 3.15.x | 3.15.0 | 3.15.0 | 3.15.0 | 3.15.0 | 0.15.0 |
| 3.14.x | 3.14.0 | 3.14.0 | 3.14.0 | 3.14.0 | 0.14.0 |
| 3.13.x | 3.13.0 | 3.13.0 | 3.13.0 | 3.13.0 | 0.13.0 |
| 3.3.x | 3.3.0 | 3.3.0 | 3.3.0 | 3.3.0 | 0.3.0 |
| 3.2.x | 3.2.0 | 3.2.0 | 3.2.0 | 3.2.0 | 0.2.0 |
| 3.1.x | 3.1.0 | 3.1.0 | 3.1.0 | 3.1.0 | 0.1.0 |
| 2.6.x | 2.6.0 | 2.6.1 | 2.6.0 | 2.6.0 (subset) | — |
| 2.4.x | 2.4.0 | 2.4.0 | 2.4.0 | 2.4.0 (subset) | — |
| 2.3.x | 2.3.0 | 2.3.0 | 2.3.0 | — | — |
| 2.2.x | 2.2.0 | 2.2.0 | 2.2.0 | — | — |
| 2.1.x | 2.1.0 | 2.1.0 | 2.1.0 | — | — |
| 2.0.x | 2.0.0 | 2.0.0 | 2.0.0 | — | — |
| 1.0.x | 1.0.0 | 1.0.0 | — | — | — |
See compatibility-matrix.md for the full table.
Every published package declares its MinSpecVersion /
__min_spec_version__ so the runtime can verify compatibility.
# C# (after the NuGet package is published)
dotnet add package VMx
# Source checkout today
dotnet add MyApp.csproj reference ../VMx/langs/csharp/src/VMx/VMx.csproj
# Python (latest public package may lag this source tree)
pip install vmx
# or
uv add vmx
# TypeScript (after the npm package is published)
npm install @thekaveh/vmx rxjs
# Source checkout today (after building langs/typescript)
npm install ../VMx/langs/typescript rxjs
# Rust (source-tree path dependency today)
cargo add vmx-rs --path langs/rustdocs/content/getting-started/csharp.md— build a modeledComponentVM<UserModel>, wire aRelayCommand, manage aCompositeVM<TabVM>.docs/content/getting-started/python.md— same shape, snake_case API, immediate / asyncio dispatchers.docs/content/getting-started/typescript.md— camelCase API, ESM imports, rxjs-backed observables.docs/content/getting-started/swift.md— camelCase API, Combine-backed publishers, SwiftPM install (Swift flavor is at total parity on the v3.22.0 source line; seelangs/swift/README.md§5).docs/content/getting-started/rust.md— Rust source-tree tutorial (ComponentVm, RelayCommand, CompositeVm with selection), withlangs/rust/README.mdfor crate commands and a minimal example.
Four UI-backed flagship Notes Workspace apps, plus a Rust-native Ratatui
showcase, exercise the VMx API in their host ecosystems. The four UI-backed
apps implement the shared scenario matrix and 19 distinct VMx features
(notebooks tree,
paged + filterable notes list, strict FormVM editor with validation,
capability-aware action bar, notifications, async lifecycle, dialogs,
AggregateVM6 root, the ThemeVM scenario contract, token-paged global
search, edit/preview DiscriminatorVM, and tag autocomplete via
SearchableState). See
examples/notes-showcase-parity.md for
the cross-flavor feature matrix and
spec/proposals/2026-05-29-notes-showcase-scenario.md
for the canonical scenario contract. The VM hierarchy is diagrammed at
examples/assets/notes-showcase-vm-hierarchy.svg;
the companion VMx component map is at
examples/assets/notes-showcase-vmx-components.svg.
The scenario is deliberately an en-US reference host; translated application
catalogs are consumer-owned and are not a parity-matrix row.
examples/csharp/avalonia/NotesShowcase/— Notes Workspace flagship on Avalonia 11 + .NET 8 (cross-platform XAML). Run:dotnet run --project examples/csharp/avalonia/NotesShowcase.examples/python/textual/notes_showcase/— Notes Workspace flagship on Textual ≥ 0.80 (TUI). Run:uv run --project examples/python/textual/notes_showcase python -m notes_showcase.examples/typescript/react/notes-showcase/— Notes Workspace flagship on React 19 + Vite. Run:npm ci && npm run devfrom the example dir; production bundle vianpm run build.examples/swift/notes-showcase/— Notes Workspace flagship on SwiftUI + Combine (macOS). Build and test viaswift build/swift testfrom the example dir (requires macOS + Xcode).examples/rust/tui/notes-showcase/— Rust-native Ratatui showcase with a pure VMx MVVM layer. Smoke-run viacargo run --locked --manifest-path examples/rust/tui/notes-showcase/Cargo.toml -- --smoke. Its five VM-layer tests cover the Rust-native showcase contract; theTHEME-001..005UI scenario matrix remains scoped to the four flagships. The VM-layer diagram isdocs/assets/diagrams/rust-tui-notes-showcase.svg.
Smaller per-flavor demos:
examples/csharp/console/HelloVMx/— console.examples/csharp/wpf/TodoApp/— WPF + MVVM (Windows only).examples/python/console/hello_vmx/— console.examples/python/tk/todo_app/— Tkinter MVVM.examples/python/textual/inspector/— Textual TUI inspector that introspects any VMx tree usingvmx.tree.walk.examples/typescript/console/hello-vmx/— minimal Node script.examples/rust/console/hello-vmx/— minimal Cargo console demo usingComponentVmandRelayCommand.
.
├── spec/ language-neutral specification (source of truth)
│ ├── 00-overview.md ... 23-async-resource-vm.md (24 chapters)
│ ├── ADRs/ architecture decision records (0001..0124)
│ ├── fixtures/ JSON test inputs shared across flavors
│ ├── schemas/ versioned supporting machine contracts
│ ├── proposals/ mostly historical; scenario contracts may be normative
│ └── VERSION spec SemVer
├── langs/
│ ├── csharp/ VMx (NuGet) + VMx.Extensions.DependencyInjection + VMx.Notifications
│ ├── python/ vmx (PyPI)
│ ├── typescript/ @thekaveh/vmx (npm)
│ ├── swift/ VMx Swift Package (v3.22.0 source, total parity — 396 library + 5 THEME)
│ └── rust/ vmx-rs crate (source-tree only; crates.io pending)
├── examples/ runnable example apps per flavor
├── docs/content/getting-started/ per-flavor quickstart tutorials
├── docs/content/integration/ one-page UI-framework integration recipes
├── docs/maintenance/ maintenance run ledgers and audit records
├── tools/ cross-cutting scripts (conformance coverage)
├── assets/ architecture + class diagrams, notes-showcase assets
├── .github/ issue/PR templates + CI workflows
└── compatibility-matrix.md
This README is the entry point; the documents below add focused detail.
CONTRIBUTING.md— spec / ADR / conformance workflow, per-flavor build commands, pre-commit setup. Read before opening a PR.SECURITY.md— supported-version table and how to report vulnerabilities.CODE_OF_CONDUCT.md— Contributor-Covenant community guidelines.compatibility-matrix.md— spec ↔ flavor version pairing.spec/README.md— index of the 24 chapters, 124 ADRs, 4 fixtures, and the 401-ID conformance catalog.spec/ADRs/README.md— ADR catalogue index.docs/content/primitives/disposal-contract.md— cross-flavor public disposal inventory and post-dispose contract.- Per-flavor READMEs (status, install, API surface, dev commands):
langs/csharp/README.md,langs/python/README.md,langs/typescript/README.md,langs/swift/README.md(v3.22.0 source, total parity — 396 library + 5 THEME),langs/rust/README.md. - Per-flavor CHANGELOGs (release history):
langs/csharp/CHANGELOG.md,langs/python/CHANGELOG.md,langs/typescript/CHANGELOG.md,langs/swift/CHANGELOG.md,langs/rust/CHANGELOG.md. - Per-flavor release runbooks:
langs/csharp/RELEASING.md— NuGet release pipeline forVMxplus companion packages,langs/python/RELEASING.md— PyPI release pipeline (python-testmatrix gate →pypi-pythonenvironment approval → exact-backend build → local-wheel fresh-venv smoke → Trusted-Publishing-via-OIDC PyPI upload with Sigstore (PEP 740) attestations →python-verify-publishedpublic fresh-venv smoke →python-release-notesCHANGELOG-extracted GitHub Release),langs/typescript/RELEASING.md— npm publish with provenance, andlangs/swift/RELEASING.md— SwiftPM tag + GitHub Release flow, andlangs/rust/RELEASING.md— crates.io trusted publishing and public-consumer verification. Release-please automates Python routine version bumps and CHANGELOG entries after its last-published manifest has been reconciled with a verified bootstrap release. - Per-flavor getting-started tutorials (longer walkthroughs):
docs/content/getting-started/csharp.md,docs/content/getting-started/python.md,docs/content/getting-started/typescript.md,docs/content/getting-started/swift.md,docs/content/getting-started/rust.md. - Per-flavor examples READMEs (run instructions):
examples/csharp/README.md,examples/python/README.md,examples/typescript/README.md,examples/swift/notes-showcase/README.md,examples/rust/README.md. examples/notes-showcase-parity.md— cross-flavor parity matrix for all four flagship Notes-Showcase apps (Avalonia / Textual / React / SwiftUI); 19 spec features × 4 flavors, plus hierarchy and VMx-component diagrams.docs/content/integration/index.md— one-page integration recipes for 11 UI frameworks (WPF, MAUI, Avalonia, Textual, NiceGUI, Tkinter, React, Vue, Svelte, SolidJS, SwiftUI). Each recipe shows the framework-native binding + lifecycle + dispose pattern.docs/maintenance/2026-07-01-contract-ledger.md— external dependency and tool-contract checks recorded during the maintenance run.docs/maintenance/2026-07-16-rust-capability-parity.md— tracked capability-surface and behavioural parity gaps between the source-tree Rust flavor and the four published flavors, with the canonical decision and proposed fix for each.docs/maintenance/2026-07-16-swift-notesshowcase-test-deadlock.md— the implemented Swift flagship command/test deadlock correction, including root cause, local build evidence, and the outstanding CI runtime check.tools/README.md— conformance-coverage tool and cross-cutting scripts.
Each language flavor versions independently in SemVer. The spec also versions
independently in SemVer. Every published package declares the spec version it
implements (MinSpecVersion in C#, __min_spec_version__ in Python,
__minSpecVersion__ in TypeScript, VMxVersion.minSpecVersion in Swift,
MIN_SPEC_VERSION in Rust). A
spec major bump triggers a major bump in every active flavor; a spec minor bump
(like v2.1.0) is fully backwards compatible and ships in flavors as a minor
bump.
spec/12-conformance.md enumerates 401 normative test scenarios keyed by ID
(LIFE-001, HUB-007, COMP-013, UTIL-002, CAP-020, DPROP-012,
NOTIF-010, DIA-001, FORM-001, COL-001, HIER-001, AGG-006,
AGCH-001, ARES-001, THEME-001, …) — 396 library IDs plus 5 THEME scenario IDs. All five
flavors (C# / Python / TypeScript / Swift / Rust) implement the 396 library IDs under
their registered conformance suites (langs/csharp/tests/VMx.Conformance.Tests,
langs/python/tests/conformance, langs/typescript/tests/conformance, and
langs/swift/Tests/VMxTests, and langs/rust/tests/conformance), and
tools/check-conformance-coverage.py enforces 100% coverage in CI. The four
UI-backed flavors also cover the 5 THEME-00x scenario IDs via their flagship
example apps — Swift via examples/swift/notes-showcase/ (ADR-0067). Those
four flavors are at total parity: 396 library + 5 THEME = 401; Rust has
full 396-ID library parity and intentionally has no UI scenario suite yet.
# Verify all catalog-complete flavors are at full catalog coverage
uv run --project langs/python python tools/check-conformance-coverage.py \
--require csharp --require python --require typescript --require swift --require rust
# Report all registered flavors
python3 tools/check-conformance-coverage.pySee CONTRIBUTING.md for the spec / ADR / conformance
workflow and per-flavor build instructions. The repository uses pre-commit
hooks (ruff, mdformat, dotnet format, eslint); install them with
pre-commit install.