Vue Lite - What Vue Could Remove

Do you ever consider how much of a framework you're using? And do you think about how much of what you are using is providing good value? As much as I like Vue, I have found a lot of its API to be unnecessary, so I end up using maybe 40% and ignore the rest. I want to see a "lite" version with all that stuff removed! Here's a bird's-eye view of my imaginary Vue Lite:

Vue should be admired though. Being able to easily use or not use certain features with no real side effects and without having to backfill with workarounds is a testament to good software design. But it has become bloated, which makes it harder to ramp up and learn and creates confusion around what's the optimal way to use all this API. It makes the bundle bigger too, although it's still half the size of React.

Anyway, here's my list of Vue's good parts and a very long list of the API bloat that I don't use:

The Good

I do use a bit more API than this, but these account for 99% of my API usage:

  • Single File Components - Easily the best feature of Vue. Going back to React after using Vue SFC for a little over four years has been a letdown in terms of developer experience and productivity. Vue's SFC enables a nicely packaged component with clean standards-based solutions for HTML, JS, and scoped CSS. Waiting for an official <test> section to co-locate tests. That'd be a game-changer.

  • HTML templates - My second favorite thing about Vue is having genuine HTML as the template syntax. I have no idea who thought trying to blend together JavaScript and XML (JSX) was a good idea, but I'm glad the creator of Vue understood the value of sticking with HTML.

  • v-if directive - Incredibly simple and clean when compared to JSX. I was surprised by how much I missed being able to just <div v-if="expression"> and move on with writing a template.

  • v-for directive - Again, simple and clean compared to JSX and other template syntaxes. It's just so refreshing to be able to <li v-for="item in items"> and not fiddle around with a JSX mess.

  • Computed properties - A powerful feature that applies extremely well to frontend use cases. The frontend is the last system to touch data and at this stage most data are ready to be presented to the user. A filtered table, for example, is a list of data that's been re-computed based on another list - the filter, query, and sort parameters. Thinking in terms of desired output is helpful to me and being able to define it as a simple property where Vue figures out all the dependencies and edge cases is superb.

  • Watch - I use it less often now, but still a valuable feature. So badly needs a once option! That's long overdue.

  • data - And of course the reactive state object. Intuitive, simple, clean, easy and powerful. Vue's data is worlds apart from React's useState. Go use a JavaScript Set in React state, then try it in Vue. You will cry tears of joy.

  • Not sure what the remaining 1% is, but I'm sure there's some other minor API I use.

The Bad

I recently forked Vue to experiment with creating a "lite" SFC-only version. Petite Vue is a cool idea, but I want to focus on a slimmer SFC experience with none of this extra stuff that I find offers no value and just becomes API noise and overhead.

Ok, some of this is subjective and some objective, so I'd like to hear your thoughts on these too:

  • v-text - Never used it because <div v-text="message"></div> is unintuitive and frankly just pointless. HTML is <div>My message!</div> not <div text="My message!">. Who wants to move an element's simple text content to a proprietary attribute? Makes no sense - delete!

  • v-show - Never used it because HTML already has a hidden boolean attribute for hiding elements. Also, a utility class for toggling a visually-hidden style is very easy to do or I can just use the style attribute to change display myself. There's no value here, it's API noise. Delete that too.

  • v-else, v-else-if - Never used them because v-else is just v-if="!expression" and because it can fail if the template changes. I've used Riot.js and it only has a simple if directive and it's been 1) dead simple to learn, and 2) sufficient for every situation I've needed. More API noise. Delete.

  • v-model - I use this directive infrequently and would be perfectly fine replacing it with a simple pattern. Delete.

  • v-slot, slots - Never used it, easily achieved with simple patterns, be gone unnecessary API!

  • v-pre - Never used it, seems extremely pointless. More API noise.

  • v-memo - Never needed this but I understand why it exists. Not worth the brain load or the effort (and risk) to ensure the named dependencies are correct vs. just letting it render. It's a hyper-optimization that requires eagle-eyed code reviews - no thanks. Delete.

  • v-cloak - Never used it and not relevant to SFC. Delete it.

  • v-on|bind or shorthands - One of these needs to go. It's just API noise to have both, which confuses new users of Vue and leads to inconsistent use and even debates about which one is "better". Keep one or the other and delete the extra API noise.

  • Event modifiers - All of these except .once need to go. It's incredibly easy to do all this with vanilla JS, so there's no value here and they make your mostly framework-agnostic HTML template more dependent on Vue magic. Worthless API knowledge taking up brain space and causing Vue beginners to pause. Just e.preventDefault() and move on. Delete this noise.

  • beforeCreate, beforeMount hooks - Never used them and cannot think of why someone needs these vs. using created or mounted.

  • unmounted hook - Have always used beforeUnmount for clean up (just seems more intuitive), so I'm not sure why this is necessary. Could be, but never needed it though. Delete.

  • Other hooks - I have never needed errorCaptured, renderTracked, renderTriggered, activated, deactivated, serverPrefetch. I can see why errorCaptured could be useful, but the rest seems like noise.

  • 5 built-in components - Never used any of the five built-in components and I think <Teleport> and <Suspense> are anti-patterns. Suspense in particular results in a lazy UX where no thought goes toward the holistic experience. In Reactland, users are often given a big, slow, mostly blank whole-page loading experience because of lazy use of Suspense. Don't be lazy, ditch Suspense and create a smarter UX! There are a bunch of custom events that are part of these components too. Just tons of API noise that I would remove.

  • 3 built-in elements - Never needed them, partly because of SFC. Delete.

  • render function - Nope. I dislike this approach. Single-file components with a template is what I want and need. Big delete!

  • Composition API - Tried it. And tried it again. There's no new value here and the ergonomics are a step backward. The script section becomes a dumping ground littered with reactive boilerplate. Be honest. You really took the time to study the whole file to understand how the previous dev intended for this file to be organized and you're now going to take the time to make sure everything you add to this file is in line with all the subtle logical groupings of variables and functions? Decades of software development history tells us it never happens no matter how well-intentioned. Composition API leads to the same mess as React hooks. The simple, reliable, and documented organization of the Options API is not only guaranteed to ensure more code organization than the hope and prayers approach of the Composition API, but Options API produces less noisy code too. Composition API adds 10-20% of reactive boilerplate to your JavaScript. Gross! Eliminate this entire section of the API and pretend it never happened.

  • name - Not needed if using SFC. Delete.

  • 6 of the $properties - I have never needed $options, $parent, $root, $slots, or $attrs. I find all of those are unnecessary or an anti-pattern. I have needed $watch(), but only because regular watch doesn't have the option to watch one time. Add a once option to watch and delete $watch() and those five other properties.

  • CSS modules - Totally unnecessary and adds extra brain load to an otherwise perfectly working standards-based solution that was already making Vue outshine other frameworks. Pure noise. Zero value. Delete. Delete it twice!

  • v-bind in CSS - Use CSS Custom Properties or dynamically set the style attribute, which is really easy to do. Delete it to death!

Future of Vue Lite

Not sure if I'll ever finish and release it, but I'm sure I'm not the only Vue fan who wishes the framework would shed the bloat and ship a "lite" version.

Imagine Vue 4 dumps all this stuff...Vue could bake in SFC, dump the Composition API and all that other noise, drop its weight down to like 6kb, and possibly unseat Riot as the cleanest and easiest JavaScript framework.

Or maybe I just go use Riot🤷‍♂️