MVCFM: Client-side MVC Framework
A reactive client-side MVC framework built from scratch in JavaScript ES6, inspired by Angular. Implements two-way data binding via ES6 Proxy, non-destructive template interpolation, and a secure conditional directive engine.
Overview
MVCFM is a client-side MVC framework built from scratch in vanilla JavaScript ES6 (no React, no Vue, no Angular). The goal was to deeply understand how reactive frontend frameworks implement two-way data binding, template rendering, conditional rendering, and declarative event handling before using them.
The framework uses the ES6 Proxy API as its core reactive engine, mirroring how Vue 3’s reactivity system works internally.
Key Technical Contributions
Reactive Two-Way Data Binding via ES6 Proxy
Built the entire reactivity system on the native ES6 Proxy object with deep recursive interception. When any model property changes (including nested objects), the proxy intercepts the set trap, triggers a diff, and re-renders only the affected DOM nodes — without a virtual DOM.
Non-Destructive Template Interpolation
Engineered a {{key}} template syntax that caches original template strings directly on DOM text nodes. This means model updates can re-render without losing the template structure — a critical detail that naive implementations get wrong by overwriting the original template string on first render.
Secure Conditional Directives (mvcfm-if)
Implemented a conditional rendering directive using the Function constructor with model keys as formal parameters, replacing eval(). This approach:
- Eliminates XSS vulnerabilities from arbitrary string evaluation
- Prevents scope leakage by keeping model state isolated from the global scope
- Maintains the declarative syntax (
mvcfm-if="count > 5") familiar to Angular/Vue developers
Declarative Event Binding via ES6 Reflection API
Designed a mvcfm-click directive using Reflect.get and Reflect.apply to dispatch DOM events to ES6 class-based controller methods. This allows declarative event-to-method binding without any implicit eval or fragile string-based dispatch.
What I Learned
Building MVCFM gave me a deep intuition for concepts that React/Vue/Angular abstract away:
- Why Vue 3 moved from
Object.defineProperty(Vue 2) toProxy(Vue 3), and the actual limitations of defineProperty - Why the virtual DOM exists and what problems it solves vs. direct DOM mutation
- How Angular’s change detection works conceptually (zone-based vs. signal-based)
- The XSS attack surface in template engines and how production frameworks mitigate it
Stack
| Layer | Technology |
|---|---|
| Core Reactivity | ES6 Proxy with recursive interception |
| Template Engine | Custom {{key}} parser with TextNode caching |
| Conditional Rendering | Function constructor (sandboxed eval) |
| Event System | ES6 Reflection API (Reflect.get, Reflect.apply) |
| DOM Utilities | jQuery (optional integration) |