<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/let-s-make-the-worst-vuejs-ever--kgrtdt8no" -->

---
title: Let's make the worst VueJS ever! | daily.dev
description: A hands-on deep dive builds a minimal Vue-like reactive framework from scratch to explain how VueJS reactivity actually works. It walks through...
canonical: https://daily.dev/posts/let-s-make-the-worst-vuejs-ever--kgrtdt8no
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Let's make the worst VueJS ever! | daily.dev
og:description: A hands-on deep dive builds a minimal Vue-like reactive framework from scratch to explain how VueJS reactivity actually works. It walks through...
og:url: https://daily.dev/posts/let-s-make-the-worst-vuejs-ever--kgrtdt8no
og:image: https://api.daily.dev/og/posts/KgRTDT8no.png
og:image:alt: Let's make the worst VueJS ever!
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Let's make the worst VueJS ever!

**[zserge's blog](https://daily.dev/sources/zserge)** · 7 min read · 0 upvotes · 0 comments

## Summary

A hands-on deep dive builds a minimal Vue-like reactive framework from scratch to explain how VueJS reactivity actually works. It walks through Object.defineProperty getters/setters, a sandboxed expression evaluator using new Function, dependency tracking via proxies, and a small set of directives (q-text, q-on, q-bind) that mimic Vue's template bindings. The full working example is around a hundred lines of code, with source published on GitHub, and closes by noting Vue 3 replaced defineProperty with ES6 Proxy/Reflect, left as an exercise for readers to implement.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://zserge.com/posts/worst-vuejs-ever>

## Questions this post answers

### How does Vue 2's reactivity system work under the hood?

Vue 2 reactivity relies on Object.defineProperty to wrap each data property with a custom getter and setter, allowing the framework to detect when a property is read (marking it as a dependency) or written (triggering re-evaluation of dependent expressions). This lets Vue automatically update only the DOM parts tied to changed variables without a virtual DOM diffing pass.

_daily.dev surfaces deep dives like this for developers reverse-engineering how their frameworks track state._

### What did Vue 3 change about how reactivity is implemented compared to Vue 2?

Vue 3 replaced Object.defineProperty with ES6 Proxy and Reflect for its reactivity system. Proxy intercepts property access much like defineProperty getters/setters did, while Reflect lets code access object properties from inside the Proxy handler while keeping the `this` binding intact, something the older defineProperty approach couldn't do cleanly.

_Developers migrating mental models between Vue versions can track framework internals on daily.dev._

### How can I safely evaluate a JavaScript expression string like a template directive value?

A safer alternative to raw eval is wrapping the expression in a `new Function` call using a `with(this){return expr}` body, then binding it to a context object, for example `new Function('with(this){return '+expr+'}').bind(ctx)()`. This lets an expression like `s.toUpperCase()` resolve against a passed-in context object such as `{s:'hello'}`, though it's still not fully sandboxed.

_daily.dev helps developers compare approaches to safely evaluating dynamic expressions in JS apps._

## Similar posts on daily.dev

- [Vue Basics: Ultimate Guide to Vue 3 Reactivity](https://daily.dev/posts/vue-basics-ultimate-guide-to-vue-3-reactivity-l3lntlfjf) · Telerik · 52 upvotes · 1 comments
- [Learn Vue.js – JavaScript Framework Course](https://daily.dev/posts/learn-vue-js-javascript-framework-course-ghtoannjz) · freeCodeCamp · 24 upvotes · 0 comments
- [Vue 3 Composition API: Watcher Lifecycle & Leak Prevention](https://daily.dev/posts/vue-3-composition-api-watcher-lifecycle-leak-prevention-ooxgpgm9h) · SitePoint · 1 upvotes · 0 comments
- [Proxy and Reflect](https://daily.dev/posts/proxy-and-reflect-i2kxp0yxx) · Piccalilli · 1 upvotes · 0 comments
- [Testing Vue components in the browser](https://daily.dev/posts/testing-vue-components-in-the-browser-dpapbjehk) · Julia Evans · 3 upvotes · 1 comments

---

Tags: [#javascript](https://daily.dev/tags/javascript), [#frontend](https://daily.dev/tags/frontend), [#vuejs](https://daily.dev/tags/vuejs), [#design-patterns](https://daily.dev/tags/design-patterns)

[View this post on daily.dev](https://daily.dev/posts/let-s-make-the-worst-vuejs-ever--kgrtdt8no)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Let's make the worst VueJS ever!","url":"https://daily.dev/posts/let-s-make-the-worst-vuejs-ever--kgrtdt8no","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/let-s-make-the-worst-vuejs-ever--kgrtdt8no"},"datePublished":"2026-08-23T10:20:13.821Z","dateModified":"2026-08-23T10:20:46.898Z","description":"A hands-on deep dive builds a minimal Vue-like reactive framework from scratch to explain how VueJS reactivity actually works. It walks through...","image":"https://media.daily.dev/image/upload/s--VDukGCjf--/f_auto/v1722860399/public/Placeholder%2002","thumbnailUrl":"https://media.daily.dev/image/upload/s--VDukGCjf--/f_auto/v1722860399/public/Placeholder%2002","isAccessibleForFree":true,"articleSection":"zserge's blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"zserge's blog","logo":"https://media.daily.dev/image/upload/s--KQnFBOIT--/f_auto,q_auto/v1787480407/logos/zserge","url":"https://daily.dev/sources/zserge"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/let-s-make-the-worst-vuejs-ever--kgrtdt8no","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"javascript,frontend,vuejs,design-patterns","timeRequired":"PT7M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"zserge's blog","item":"https://daily.dev/sources/zserge"},{"@type":"ListItem","position":3,"name":"Let's make the worst VueJS ever!"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/let-s-make-the-worst-vuejs-ever--kgrtdt8no#faq","mainEntity":[{"@type":"Question","name":"How does Vue 2's reactivity system work under the hood?","acceptedAnswer":{"@type":"Answer","text":"Vue 2 reactivity relies on Object.defineProperty to wrap each data property with a custom getter and setter, allowing the framework to detect when a property is read (marking it as a dependency) or written (triggering re-evaluation of dependent expressions). This lets Vue automatically update only the DOM parts tied to changed variables without a virtual DOM diffing pass. daily.dev surfaces deep dives like this for developers reverse-engineering how their frameworks track state."}},{"@type":"Question","name":"What did Vue 3 change about how reactivity is implemented compared to Vue 2?","acceptedAnswer":{"@type":"Answer","text":"Vue 3 replaced Object.defineProperty with ES6 Proxy and Reflect for its reactivity system. Proxy intercepts property access much like defineProperty getters/setters did, while Reflect lets code access object properties from inside the Proxy handler while keeping the `this` binding intact, something the older defineProperty approach couldn't do cleanly. Developers migrating mental models between Vue versions can track framework internals on daily.dev."}},{"@type":"Question","name":"How can I safely evaluate a JavaScript expression string like a template directive value?","acceptedAnswer":{"@type":"Answer","text":"A safer alternative to raw eval is wrapping the expression in a `new Function` call using a `with(this){return expr}` body, then binding it to a context object, for example `new Function('with(this){return '+expr+'}').bind(ctx)()`. This lets an expression like `s.toUpperCase()` resolve against a passed-in context object such as `{s:'hello'}`, though it's still not fully sandboxed. daily.dev helps developers compare approaches to safely evaluating dynamic expressions in JS apps."}}]}
```

