Skip to content
bretuobayPublic

About

Web Loom is a lightweight, framework-agnostic toolkit offering MVVM architecture, state stores, event bus utilities, and headless UI behaviors for modern web apps.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

768 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Web Loom Logo

Web Loom — A Framework-Agnostic UI Architecture Toolkit

License: MIT npm

Web Loom is a growing ecosystem of framework-agnostic patterns for the web, built around signals and MVVM. Business logic lives in Models and ViewModels that don't import React, Vue, Angular, or anything else — only the View layer changes when you change your mind about a framework, and Web Loom now ships its own native View too, so you don't have to pick a framework at all.

Vision

In an ever-evolving landscape of frontend frameworks, Web Loom champions a timeless approach to UI architecture. Inspired by the robust patterns of C#'s Prism framework, we've adapted and enhanced these concepts for the modern web with reactive signals in place of RxJS/WPF-style dependency properties. The goal: your core logic — Models, ViewModels, Commands, validation — pays dividends for years, independent of whichever framework is fashionable this year.

Two Ways to Build

Every Web Loom app starts the same way: a @web-loom/mvvm-core BaseViewModel exposing signal-backed state (data$, isLoading$, error$) and Commands from @web-loom/signals-core. What differs is the View.

1. Bring your own framework

Write a thin bridge that subscribes your framework's rendering model to the ViewModel's signals. Every demo app in apps/ does exactly this, in a few lines:

App Framework How it bridges to the ViewModel's signals
apps/mvvm-react React useSignal(sig) → useSyncExternalStore(sig.subscribe, sig.get, sig.get)
apps/mvvm-vue Vue 3 useSignal(sig) → shallowRef seeded via .peek(), synced via observe()
apps/mvvm-solid SolidJS useSignal(sig) → Solid createSignal seeded via observe(); view uses <Show>/<For>
apps/mvvm-angular Angular fromLoomSignal(sig, destroyRef) → mirrors into a native Angular signal()
apps/mvvm-lit Lit manual @state() field updated via observe() in connectedCallback
apps/mvvm-marko Marko subscribeToObservable(sig, updateFn) wrapping observe/subscribe
apps/mvvm-vanilla Vanilla JS + EJS direct observe(vm.data$, callback) calls that manually patch the DOM
apps/mvvm-react-native React Native same bridge as mvvm-react, native components
apps/mvvm-react-integrated React React + Design Core theming, integrated patterns

Reach for this path when you want a specific framework's ecosystem, tooling, or team familiarity.

2. The complete Web Loom stack

Or skip the bridge entirely: @web-loom/template-core renders the same ViewModels directly, because its bindings are signal subscriptions. No virtual DOM, no component re-render, no adapter code.

import { signal } from '@web-loom/signals-core';
import { compile } from '@web-loom/template-core';

const vm = { count$: signal(0), increment: () => vm.count$.update((n) => n + 1) };

const template = compile(`<button on:click="increment">Count: {{ count$ }}</button>`);
const view = template.mount(document.getElementById('app')!, vm);
// later: view.dispose()

apps/ecommerce-template-core is the ecommerce proof: a full catalog/cart/checkout/SSR app built with zero JS framework — only signals-core, mvvm-core, and template-core. apps/mvvm-template-core is the same idea for the greenhouse dashboard: it clones apps/mvvm-react with .loom templates instead of React components, sharing the same ViewModels. apps/ecommerce-mvvm is the React ecommerce sibling.

template-core and its tooling siblings are implemented and used across the demo apps but not yet published to npm — see Packages below. Use them today via the workspace; npm install support is coming.

Core Principles

  • Framework-Agnostic: Core libraries work with any frontend framework, or with no framework at all.
  • Signals-First Reactivity: @web-loom/signals-core provides signal/computed/effect primitives with no virtual DOM required — the same signal graph drives every View option above.
  • MVVM Architecture: A complete Model-View-ViewModel implementation for clean separation of concerns and testable business logic.
  • Headless UI: UI patterns provide logic and behavior for common components without imposing any styling.
  • Plugin System: A dynamic plugin architecture for modular, extensible applications.
  • Type-Safe: The entire ecosystem is TypeScript, with Zod validation at the Model boundary.

Getting Started

The fastest way to start a new project is the create-web-loom CLI, which scaffolds a Vite app and overlays a working, signals-backed MVVM starter:

npm create web-loom@latest

It detects your chosen framework (React, Preact, Vue, Solid, Svelte, Lit, Vanilla, or Qwik) and wires up a starter ViewModel plus the matching signal bridge automatically.

To explore this monorepo itself — all the demo apps, template-core, and the ecommerce comparison — clone and install (the workspace uses pnpm):

pnpm install
pnpm dev

Packages

All packages version in lockstep in the 0.8.x line (currently 0.8.0; signals-core is at 0.8.1 in the repo) until the API surface is ready to commit to 1.0.0 — no package's version exceeds mvvm-core/signals-core, the two most-exercised packages in the ecosystem, and releases between now and 1.0.0 are patch-only (see Versioning Policy).

Published

These are live on npm today.

Package Description
@web-loom/mvvm-core Signals-backed MVVM framework — BaseModel, RestfulApiModel, BaseViewModel, Command
@web-loom/signals-core Framework-agnostic reactive signals — signal, computed, effect, batch
@web-loom/query-core Server state management with caching, deduplication, and background refetch
@web-loom/store-core Minimal client state management for UI-only state
@web-loom/ui-core Headless UI behaviors — Dialog, Form, List Selection, Roving Focus, Drag & Drop
@web-loom/ui-patterns Composed UI patterns built on ui-core — Wizard, Master-Detail, Command Palette
@web-loom/design-core Design tokens and theming system
@web-loom/forms-core Framework-agnostic form state management with Zod integration
@web-loom/event-bus-core Type-safe pub-sub event bus for cross-feature communication
@web-loom/event-emitter-core Tiny type-safe event emitter shared across Web Loom packages
@web-loom/mcp-server MCP server exposing scaffolding, docs, and guided patterns for @web-loom/*
create-web-loom CLI scaffolder — npm create web-loom@latest

Framework-specific adapters (React/Vue/vanilla form bindings, media players, charts) live in the sibling web-loom-extensions repo. They use the same @web-loom/* package names but are not on npm yet.

Coming soon

Implemented in this repo (most are used by the demo apps), but not yet published to npm — use via the workspace in the meantime.

Package Description
@web-loom/template-core Signal-native reactive template engine — no VDOM, no framework adapter
@web-loom/template-core-vite Vite plugin for template-core — build-time precompile, dev analyze/precompile modes
@web-loom/template-core-vite-ssr Reusable Vite SSR dev/production server for template-core apps
@web-loom/template-core-lint ESLint plugin with static-analysis rules for template-core templates
@web-loom/template-core-tooling Shared AST utilities and source-linked diagnostics behind the two packages above
@web-loom/template-core-router router-core adapter for template-core route outlets
@web-loom/view Component model (defineComponent) on top of template-core
@web-loom/mvvm-patterns Application-level MVVM patterns — interaction requests, active-aware ViewModels
@web-loom/embed-core Framework-agnostic embeddable widget SDK and host integration layer

Internal / workspace-only

A supporting cast used by the demo apps and not meant for external installation: shared domain models and ViewModels (@repo/models, @repo/view-models, @repo/shared), the plugin registry (@repo/plugin-core), infrastructure libraries still maturing toward a first release (http-core, storage-core, platform-core, notifications-core, router-core, error-core, i18n-core, typography-core), the docs site theme (@repo/docs-theme), the editor extension (vscode-template-core-syntax), and internal tooling config (@repo/eslint-config, @repo/typescript-config).

Versioning Policy

Every package in this repo — published, coming-soon, or internal — moves in lockstep and stays at or below mvvm-core/signals-core's version. Until the ecosystem is ready to commit to a stable public API, releases are patch-only: no package's major.minor changes without a deliberate, repo-wide decision to cross into 1.0.0. A CI check enforces this on every pull request; see .claude/skills/versioning.md for the full policy and rationale.

Templating: @web-loom/template-core

template-core is a Mustache/Handlebars-flavored HTML template engine whose bindings are signals-core subscriptions — a signal write updates exactly the DOM node or attribute that reads it, nothing else re-renders.

<h1>{{ title$ }}</h1>
{{#if isLoading$}}
<p>Loading…</p>
{{else if error$}}
<p>{{ error$ }}</p>
{{/if}} {{#each todos$ key=id}}
<li on:click="remove(this)">{{ text }}</li>
{{else}}
<li>Nothing to do</li>
{{/each}} <input bind:value="name$" />

Templates compile at runtime via the browser's native <template> parser plus a small CSP-safe expression evaluator (no eval/new Function), or precompile offline to a serializable render plan for production builds. It also supports SSR/hydration without a DOM, via parse5.

It isn't meant to replace the React/Vue/Angular/Lit/Marko adapters in general — it's Web Loom's own reference View, the one that keeps the rest of the ecosystem honest about the ViewModel boundary. Its tooling packages (template-core-vite, template-core-vite-ssr, template-core-lint, template-core-tooling, vscode-template-core-syntax) round out the authoring experience with build-time precompilation, SSR, linting, and editor syntax highlighting.

See packages/template-core/README.md and its PRD for the full grammar and design rationale. apps/mvvm-template-core is the .loom greenhouse demo; apps/ecommerce-template-core is the ecommerce/SSR reference.

Architecture

Web Loom's architecture is heavily inspired by the C# Prism framework, reimagined around reactive signals (@web-loom/signals-core) and TypeScript. For the full package dependency graph, see paper/architecture-overview.md.

MVVM (Model-View-ViewModel)

┌─────────────────────────────────────────────────────────┐
│                         View Layer                       │
│   Any framework (React/Vue/Angular/Lit/Marko/Vanilla)    │
│              — or @web-loom/template-core                │
└────────────────────┬────────────────────────────────────┘
                     │ Binds to signals
                     ▼
┌─────────────────────────────────────────────────────────┐
│                      ViewModel Layer                     │
│    (packages/view-models - Shared Business Logic)       │
│    • Exposes data$ / isLoading$ / error$ signals        │
│    • Handles user interactions via Commands              │
│    • Framework-agnostic                                 │
└────────────────────┬────────────────────────────────────┘
                     │ Uses
                     ▼
┌─────────────────────────────────────────────────────────┐
│                       Model Layer                        │
│         (packages/mvvm-core - Data & Logic)             │
│    • BaseModel / RestfulApiModel                        │
│    • Zod validation                                     │
│    • Signal-based reactive state                        │
└─────────────────────────────────────────────────────────┘

Headless UI Patterns

Atomic Behaviors (@web-loom/ui-core)
       ↓
Composed Patterns (@web-loom/ui-patterns)
       ↓
Framework-Specific Components — or template-core, directly

Plugin Architecture

┌────────────────────────────────────────┐
│         Plugin Host Application         │
│  (Loads and manages plugins at runtime) │
└──────────────┬─────────────────────────┘
               │
        ┌──────┴──────┐
        │ Plugin Core │ (Framework-agnostic registry)
        └──────┬──────┘
               │
    ┌──────────┼──────────┐
    ▼          ▼          ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│React    │ │Angular  │ │Vue      │
│Adapter  │ │Adapter  │ │Adapter  │
└─────────┘ └─────────┘ └─────────┘

Learn More

We are excited to have you on this journey with us. Welcome to the future of UI architecture. Welcome to Web Loom.

About

Web Loom is a lightweight, framework-agnostic toolkit offering MVVM architecture, state stores, event bus utilities, and headless UI behaviors for modern web apps.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages