When we first started drafting the idea for Ovee.js, we’ve decided that we don’t want to reinvent the wheel and wanted to avoid reimplementing complex parts like reactivity or templating for the millionth time. It’s a popular principle among back-end frameworks - Laravel heavily reuses parts of Symfony, Symfony by default comes bundled with Doctrine, Nest depends on Express (which even can be replaced with other implementation on demand). Yet, in the front-end field, each of the big frameworks is built fully independently (correct me, if I’ve missed something).
For the initial build of Ovee.js, we’ve chosen on-change for handling simple reactivity, and lit-html for templating. We’ve also built an optional module on top of Barba for asynchronous page transitions. This decision helped us to ship the first working version of the framework relatively fast, avoiding major bugs in the potentially most complex parts.
Since the release of Vue 3, we started to tinker with its internals and decided to eventually replace on-change with much more capable solution.
More power with Vue 3 modules
Vue 3 brought great, well-received changes to its API. But from our point of view, we also got two really important changes, that might get overlooked by most developers.
First thing is that the reactivity got rewritten to Proxy API, which solves the constraints of the previous implementation, and is much more clean and modern. For Ovee.js, we intended to use Proxy API from the very beginning, which is why we couldn’t rely on Vue 2 reactivity for the initial build.
Second, an even more important change is that Vue is now shipped in modular form, and parts of the framework are available as separate NPM packages. This way, we can use @vue/reactivity
without having the whole framework as a dependency. And when it comes to the number of dependencies, a smaller footprint means faster installation and smaller node_modules
.
The experience of using independent parts of Vue 3
As we intended to only replace the Ovee’s reactivity, we’ve added @vue/reactivity
and @vue/runtime-core
to our dependency tree. The first one, just as the name suggests, gave us tools to rebuild our ReactiveProxy
class. Usage is super easy:
import { reactive } from '@vue/reactivity';
const proxy = reactive({});
The latter brings watch
, computed
, and watchEffect
. Earlier, we had @watch
decorator, but with our own implementation. Now, we could just use watch
from @vue/runtime-core
package. Going further, we added 2 new decorators: @watchEffect
and @computed
, which just wrap their respective methods.
But that’s not everything! The TemplateComponent
from Ovee.js also relyed on watch and reactivity system, to automatically re-render lit templates when any of the reactive data changes. We replaced it with helpful watchEffect
underneath, which ultimately reduced lines of code and simplified how the system worked.
Currently, we only replaced the old reactivity system and added a few wrappers. But Vue reactivity system is so versatile, we can build a lot of cool new features as part of the core package and new modules as well! Of course, the same benefits are now available to the developers using Ovee.js.
Overall, the whole Vue reactivity system is well documented and easy to use. It is also written in TypeScript, with very good typings, which is also a big con for us, as we use TypeScript as well.
Wait, so what’s that Ovee.js thing?
Ovee.js is a component framework designed to work with server-side rendered markup. It means that it is not a competition for Vue or React, but rather a modern approach for projects, where we would use jQuery in the past. You can read more about Ovee.js here and take a peek at the official documentation.