A hierarchical, lifecycle-aware MVVM viewmodel framework — one language-neutral specification, four idiomatic language flavors (C# / Python / TypeScript / Swift at total parity), 281 library conformance IDs + 5 THEME scenario IDs = 286 total verified by path-filtered CI on relevant changes (all four flavors, including the Swift notes-showcase flagship).
- 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. - A
RelayCommandwith reactivecanExecutetriggers, 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. DerivedProperty<T>for N-source computed values,FormVM<T>for snapshot/revert/validation flows,DiscriminatorVMfor single-active-key coordination,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 shape is identical across flavors; only the surface idiom changes (PascalCase in C#, snake_case in Python, camelCase in TypeScript and Swift — codified in ADR-0006).
The diagram source 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 class map of the entire library — what every class family is, and how the families relate.
The diagram source 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. Five bands:
- Lifecycle base —
ComponentVMBase+ConstructionStatus; every VM derives from here. - VM family — five idioms: leaf, composite (homogeneous + selectable), group (homogeneous peers), aggregate (heterogeneous, fixed arity 1..6), and specialized (
FormVM,DiscriminatorVM,NotificationVM,ConfirmationVM, forwarding decorators). - Commands & capabilities —
RelayCommandfamily +DecoratorCommandchain +ModeledCrudCommands, alongside the 22 capability micro-interfaces (Selection / Expansion / Lifecycle / Query / Dialog / CRUD). - Services · Messages · State · Collections — the constructor-injected runtime (
MessageHub,Dispatcher,ILocalizer,IDialogService— each with itsNull*sibling per ADR-0017), hub envelope types, state helpers (SearchableState,ExpandableState,DerivedProperty), observable collections,PagedComposition,TokenPagedComposition, filtered/scored composite views, fluent immutable builders, and tree utilities. - Notifications sub-package (opt-in) —
INotificationHub,ConfirmHelper, bridged toConfirmationDecoratorCommandin band 3 and toNotificationVM/ConfirmationVMin band 2.
Boxes are cluster-level (one box per related set of classes); the exhaustive member list lives in the linked spec chapters + ADRs.
Each flavor implements the same conceptual stack:
- Spec —
spec/is the source of truth: 23 markdown chapters, 79 ADRs, 4 JSON fixtures, 286 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, and reactive trigger observables. - Messages and collection events —
PropertyChangedMessage,ConstructionStatusChangedMessage,CollectionChangedEventwithBatchUpdate()andAutoConstructOnAddoptions. - Tree utilities —
walk(root),walk_expanded(root), andfind(root, predicate)over any VM hierarchy. - Services —
MessageHub(rx Subject-backed 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.1.0 in source | NuGet package not published yet | System.Reactive |
| Python | v3.1.0 in source | vmx latest published: 3.1.0 |
reactivex |
| TypeScript | v3.1.0 in source | npm package not published yet | rxjs |
| Swift | v3.1.0 in source | SwiftPM tag not published yet; no central registry | Combine |
main may contain an in-development source version before that version is
published to package registries. Use the compatibility matrix for source-level
spec parity; use each registry for installable package availability.
The Swift flavor is at total parity — all 281 library conformance IDs as
of v3.1.0 plus the 5 THEME-00x scenario IDs covered by the
examples/swift/notes-showcase/ flagship (ADR-0067) = 286 total, matching
C#, Python, and TypeScript. See langs/swift/README.md
§5 for the full 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). The Python flavor supports Python 3.10 through 3.13,
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) targets Node
≥20, emits dual ESM + CJS bundles, and exposes @thekaveh/vmx/notifications
as a sub-path export.
| spec | csharp | python | typescript | swift |
|---|---|---|---|---|
| 3.1.x | 3.1.0 | 3.1.0 | 3.1.0 | 3.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
# 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 rxjsdocs/getting-started/csharp.md— build a modeledComponentVM<UserModel>, wire aRelayCommand, manage aCompositeVM<TabVM>.docs/getting-started/python.md— same shape, snake_case API, immediate / asyncio dispatchers.docs/getting-started/typescript.md— camelCase API, ESM imports, rxjs-backed observables.docs/getting-started/swift.md— camelCase API, Combine-backed publishers, SwiftPM install (Swift flavor is at total parity as of v3.1.0; seelangs/swift/README.md§5).
The four flagship Notes Workspace apps — one per language flavor, one
per UI framework — implement the same scenario from a single language-neutral
VM API surface, exercising 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.
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 18 + 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).
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.
.
├── spec/ language-neutral specification (source of truth)
│ ├── 00-overview.md ... 22-discriminator-vm.md (23 chapters)
│ ├── ADRs/ architecture decision records (0001..0079)
│ ├── fixtures/ JSON test inputs shared across flavors
│ ├── 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.1.0, total parity — 281 library + 5 THEME)
├── examples/ runnable example apps per flavor
├── docs/getting-started/ per-flavor quickstart tutorials
├── docs/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.
- Public documentation site: thekaveh.github.io/VMx
- GitHub wiki: github.com/thekaveh/VMx/wiki
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 23 chapters, 79 ADRs, 4 fixtures, and the 286-ID conformance catalog.spec/ADRs/README.md— ADR catalogue index.- 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.1.0, total parity — 281 library + 5 THEME). - Per-flavor CHANGELOGs (release history):
langs/csharp/CHANGELOG.md,langs/python/CHANGELOG.md,langs/typescript/CHANGELOG.md,langs/swift/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 → Trusted-Publishing-via-OIDC upload with Sigstore (PEP 740) attestations →python-verify-publishedfresh-venv smoke test →python-release-notesCHANGELOG-extracted GitHub Release),langs/typescript/RELEASING.md— npm publish with provenance, andlangs/swift/RELEASING.md— SwiftPM tag + GitHub Release flow. release-please currently automates Python routine version bumps + CHANGELOG entries via Conventional Commits. - Per-flavor getting-started tutorials (longer walkthroughs):
docs/getting-started/csharp.md,docs/getting-started/python.md,docs/getting-started/typescript.md,docs/getting-started/swift.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/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/integration/README.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.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). 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 286 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,
THEME-001, …) — 281 library IDs plus 5 THEME scenario IDs. All four
flavors (C# / Python / TypeScript / Swift) implement the 281 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
tools/check-conformance-coverage.py enforces 100% coverage in CI. All four
flavors also cover the 5 THEME-00x scenario IDs via their respective flagship
example apps — Swift via examples/swift/notes-showcase/ (ADR-0067). Every
flavor is at total parity: 281 library + 5 THEME = 286.
# Verify all four flavors are at full catalog coverage
uv run --project langs/python python tools/check-conformance-coverage.py \
--require csharp --require python --require typescript --require swiftSee 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.