
Native desktop applications using Vue.js
An introduction to Vuido, a framework for creating lightweight, native desktop applications using Vue.js. Application using Vuido can run on Windows, OS X and Linux, using native GUI components, and don’t require Electron.
Modern JavaScript is almost everywhere. It transformed the web, both on the front-end and the back-end. With frameworks such as React Native and NativeScript, you can create efficient mobile applications with native user interface. What about a similar solution for the desktop?
Of course there is Electron and NW.js. They are great for creating large applications with complex user interface. But applications using those frameworks are in fact web applications, shipped with their own web browser. This adds a significant cost to the package size, memory usage and startup time. Even the simplest Electron application takes at least 120 MB of disk space.
Another problem is that applications based on Electron or NW.js don’t look like native desktop applications. Their user interface is basically HTML and CSS, not native GUI components of the operating system. Sometimes that’s a good thing, especially in case of complex applications with lots of graphics and multimedia. But if all you need is a simple window with a few controls, a native GUI would be enough, without the overhead of running a full web browser.
Native alternative to Electron
When I came across Proton Native about two weeks ago, I was really impressed. It’s a framework very similar to React Native, but designed for Windows, OS X and Linux. It allows creating lightweight JavaScript applications with native user interface, without Electron or NW.js. My first thought was: is there something similar to Proton Native, but based on Vue.js?
It turned out that there wasn’t, so I had a difficult decision to make. I’ve been working on various open-source projects for over 15 years. I love the JavaScript community, and the Vue.js community in particular, and I always felt that I should somehow contribute to it. But I also wasn’t sure if I was able do it. I doubted if I could build and maintain a community around this project, because I worked on most projects entirely on my own. I even started questioning my technical skills. Classic impostor syndrome.
But I started working on a proof of concept, and after digging into the source codes of Vue.js and nativescript-vue, it turned out that re-compiling Vue.js for a different platform wasn’t that difficult. In just a few days I created and published the first prototype of Vuido. I announced it on the Vue.js forum to get early feedback and see if it makes sense to continue working on this project.
The results exceeded my expectations. Vuido received the first one thousand stars on GitHub in less than three days and it became the third top trending project. I also got the New User of the Month badge on the Vue.js forum with congratulations from Evan You, which is a great honor. But perhaps the greatest success was that an active community emerged spontaneously around Vuido.
Using Vuido
So how does Vuido work? Essentially, it’s just a slightly modified version of Vue.js. Vuido supports most of the standard Vue.js API, including methods, components and directives. It’s also compatible with many Vue.js extensions, for example Vuex. And since applications using Vuido run in a Node.js environment, they can use both the standard Node.js API and any packages which are compatible with Node.js.
The simplest Vuido application looks like this:
import libui from 'libui-node'
import Vue from 'vuido'import MainWindow from './components/MainWindow'const window = new Vue({
render: h => h(MainWindow)
});window.$mount();libui.startLoop();
One of the most powerful feature of Vue.js is single-file components, and they are also supported by Vuido. To design the user interface of your application, you can use the standard Vue.js template syntax with a variety of containers and widgets. For example:
<template>
<Window title="Vuido Example" width="400" height="100" margined
v-on:close="exit">
<Box horizontal padded>
<Text stretchy>Counter: {{ counter }}</Text>
<Button v-on:click="increment">Increment</Button>
</Box>
</Window>
</template>
In order to use single-file components with Vuido, you need to compile your application using webpack. Since configuring webpack with vue-loader and a special version of the Vue.js template compiler is quite difficult, I created a template which can be used with vue-cli to initialize a new Vuido application. You can use it like this:
vue init mimecorg/vuido-webpack-template my-project
You can find more information about using Vuido in the documentation.
Packaging a Vuido application
Applications created using Vuido are native in the sense that they use the native GUI components provided by the operating system: WinAPI on Windows, Cocoa on OS X and GTK+ on Linux. This works thanks to the portable libui library and libui-node which provides JavaScript bindings for libui.
However, applications using Vuido, and libui-node in general, still need Node.js to run. Most regular users don’t have Node.js installed and don’t know how to install packages using npm and run them using the command line. So these applications must be shipped with the Node.js executable.
The problem is that Node.js is designed for command line applications, not GUI applications. It means that:
- You have to create a wrapper shell script which runs Node.js with correct arguments. Some users will try to run the Node.js executable, not the wrapper script.
- A console window is opened when you run the application.
- If there is an error, it is printed to the console, which is then immediately closed.
To solve these problems, I created another project called LaunchUI. It wraps Node.js with a small executable which automatically runs your application. No console window is opened and in case of a fatal error, it is reported using a message box.
A simple Vuido application packaged using LaunchUI takes about 20 MB, which is much less than the size of Electron and NW.js applications. It also requires less memory and there is less delay on startup.
When I announced Vuido, I said that it could eventually replace Qt as a framework for creating lightweight, cross platform applications. Of course that was a bit humorous, but it’s not as crazy as it sounds. Qt became a massive framework with lots of modules, including its own web engine based on Chromium. Even stripped down to the bare minimum, the size of a simple Qt application is about 15–20 MB, so it’s comparable to Node.js.
Besides, JavaScript is currently the most popular programming language, it’s easier to learn than C++, and the number of available npm packages far exceeds any other repository. Because of that, I believe that native GUI applications using Node.js will sooner or later become reality.
The future of Vuido
It all sounds very exciting, but keep in mind that both Vuido and the underlying technologies — libui and libui-node — are currently in an early stage of development. As Pietro Gagliardi, the author of libui, pointed out recently:
“libui is currently mid-alpha software. Much of what is currently present runs stably enough for the examples and perhaps some small programs to work, but the stability is still a work-in-progress, much of what is already there is not feature-complete, some of it will be buggy on certain platforms, and there’s a lot of stuff missing.”
The same is obviously true when it comes to Vuido. All these projects are developed by a relatively small group of people in their free time, but libui, libui-node and Proton Native have been very active in the last few months, and I also intend to keep working on both Vuido and LaunchUI.
I hope that more developers will join and contribute to these projects, because they have the potential to change desktop applications in the same way as React Native and NativeScript changed mobile ones.
Edit (9/24/2018): I recently wrote a follow up article about creating a real life application using Vuido. Also make sure to read this great introduction to using Vuido, written by Natalia Tepluhina.
✉️ Subscribe to CodeBurst’s once-weekly Email Blast, 🐦 Follow CodeBurst on Twitter, view 🗺️ The 2018 Web Developer Roadmap, and 🕸️ Learn Full Stack Web Development.