What follows is part one in a series of articles in which I build a blog using both VueJS and Svelte. To be clear, I’m actually going to be building two blogs simultaneously — one for each framework. In the first part of this article, I’ll discuss the tools I’ll be using, and also why the heck I’d want to do this.
In the second part, I’ll go over the steps needed to lay the foundation for future work. At the end of this post, we’ll have two minimal sites deployed at publicly available URLs.
Once the blogs are finished (aside from applying some final CSS), I’ll do an evaluation of the two sites and make a determination about which one to keep and use for my personal blog. The “winning” framework will also be used to rebuild the JavaScript Report site, which is now on Ghost CMS.
The criteria for “best” framework are:
- Performance. The site needs to render in 2 seconds on 3G mobile.
- Ease of use. As I try to complete what will ultimately be a fairly simple blog, do I hit any roadblocks? Is there something missing I need to write from scratch?
- How well do I think the framework will scale? As I go along, I’m going to be looking for potential issues if I decided to use the framework to build something more complex.
If you want to skip ahead and get started building stuff, you can continue reading here. Otherwise, I’d like to explain a bit more about the how and why of this project.
The Tools
Aside from VueJS and Svelte, there are a number of other tools that I’ll need to use. The first is the Now hosting service from Zeit. If you haven’t heard of Now, this will be a chance for you to see how to use it. It’s very easy to get started with, but part of this exercise for me is to see if I’d actually want to host a production site with them. Server response time will be a very big consideration.
Another tool I’ll be using is Contentful, which is a “headless” CMS service. It provides a slick web-based content editor as well as solid image hosting. Your content is then made available via a REST API.
For small sites, Contentful ends up being essentially free, but it has the ability to scale to pretty much whatever size you need it to (pay as you go), and that makes it a great all-around option. Contentful does have experimental support for GraphQL, but that is something for another series of articles. For the purposes of what I’m doing, good old REST is just fine.
Finally, I’ll need to integrate MailChimp. JavaScript Report has a newsletter (which you should definitely sign up for!), and so I’d like to see if there are any issues getting that up and running with either framework, though it's unlikely to be a problem.
Why the Heck Am I Doing This?
For the past 3+ years, I’ve been building React sites at a client services company. I appreciate React and the many things I’ve learned while working with it, but I’ve increasingly felt a need to branch out.
As I’ve explored other frameworks, I’ve seen a number of things that have looked really impressive. For starters, there are quite a few frameworks that have superior performance to React. In the case of Svelte, it’s much faster, and in the case of Vue, only slightly faster.
I’ve also come to appreciate the simplicity of single file components, which both VueJS and Svelte implement. Doing something similar in React feels convoluted by comparison.
I’ve also heard that VueJS is much easier to learn than React, and what I’ve seen so far backs that up. My early experience learning Svelte is similar. Simplicity is good! But are there any tradeoffs? I haven’t found any so far, but part of this exercise is confirming that.
Both frameworks also have good communities (although Vue’s is much larger) as well as maintainers I’m familiar with and have confidence in. And I'm evaluating both because I want to compare them head to head to find out which one offers the most benefit. They have roughly similar approaches, so they are a particularly good pairing.
As I get started, I have to say Svelte starts with a lead because it has elite-level performance. It's very fast, and ultimately, excellent performance is one of the few things that has a measurable impact for end users. If that performance comes with a lot of friction (hard to do common tasks, for example), then that makes Vue more attractive.
So, we’ll see how it unfolds.
Getting Started with Now
The first step is the same for both frameworks — getting set up to use the Now hosting service. Fortunately, it’s very easy to get started.
Step One
Download Now Desktop. It makes deployments a breeze. It installs the Now CLI and keeps it up to date automatically.
Step Two
Sign up for the Now service. You’ll be walked through the process once you open the Now Desktop app.
And that’s it! Once we have the basic scaffolding for our apps, we’ll be able to deploy with a single command.
Setting Up Vue
We’ll begin with Vue by installing the CLI. The CLI (command line interface) provides a way to quickly scaffold a project. If you don’t already have the CLI installed, go to your command line and enter one of the following commands, depending on whether or not you have yarn installed.
yarn global add @vue/cli
# or
npm install -g @vue/cli
By the way, the version of the CLI I’m using is 3.0.0-beta.6. It has some nice improvements over the 2.x version.
Install Using the CLI
Now that the CLI is installed, I’ll use it to provide a basic setup for the project.
vue create vue-blog
After entering the command above, you’ll be prompted to answer a series of questions about what you want the CLI to create for you. If you’re following along, here are the selections I made. The initial prompt asks you to pick a preset. I chose “Manually select features”.
Vue CLI v3.0.0-beta.6
Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
Manually select features
The next step is a list of options:
❯◯ TypeScript
◯ Progressive Web App (PWA) Support
◯ Router
◯ Vuex
◯ CSS Pre-processors
◯ Linter / Formatter
◯ Unit Testing
◯ E2E Testing
The options I chose to get started were:
- Progressive Web App (PWA) Support
- Router
- Vuex (state management)
- CSS Pre-processors (SCSS/SASS)
- Linter / Formatter (ESLint + Prettier, Lint and fix on commit)
I will add both of the testing options later, but that feels like an entirely different series of blog posts, and there is already quite a lot going on with just getting these sites built. If this was for a client project, I’d be writing tests from the start.
After that step, there are a couple additional question you’ll be prompted to answer:
Where do you prefer placing config for Babel, PostCSS, ESLint, etc.?
In dedicated config files
❯ In package.json
I chose package.json for this one. Next you’ll be asked about your dependency management tool.
Pick the package manager to use when installing dependencies: (Use arrow keys)
❯ Use Yarn
Use NPM
I chose yarn here, but it doesn’t matter much for the purposes of this exercise.
And that’s pretty much it! Open the directory that was created — if you followed along above it will be named vue-blog — and take a look at what has been created.
You’ll see there are a whole bunch of files that have been generated. Pretty nice! If you wanted to fire up your app in dev mode, all you’d need to do is type npm run serve
and you’d have a dev server spin up for you. But for the present work, that’s not what is needed. There are a couple extra steps.
Add server.js
First, add a new file to the project root called server.js. The contents of the file should look like this:
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'dist')));
const port = process.env.PORT || 5000;
app.listen(port);
console.log('server started ' + port);
This will create a web server using Express, which is preferred over the Vue dev server.
In order to use Express, we’ll need to add it to the project.
npm install express
The last step is to modify the scripts in package.json.
Update package.json
By default, the Now service will look to see if a build
script exists, and if you check package.json, you’ll see that we have that in place. The only requirement for Now is a start
script, which is not present, so we’ll need to add it. Here’s the start
script I’ve added in package.json:
"start": "node ./server.js"
And now we’re ready to deploy. Assuming you have Now Desktop installed, simply type the following command into your terminal:
now
Yeah, that is all it takes. Now will spin up a deployment for you that includes SSL. Here’s the URL of the deployment for this first step in building a Vue blog.
All in all, this is pretty damn slick. Here is the link to the repo at this point in development for reference.
Now let’s do the same for Svelte.
Setting Up Svelte
If you’re not familiar with Svelte, you should know that it’s a bit different than other frameworks. It’s very fast, and that speed comes from a compilation process that essentially removes the framework’s runtime, leaving a bundle that is, well, svelte.
The Svelte CLI isn’t recommended for production use and supports compiling single components, not entire websites, so a different approach is needed. That’s where degit
comes in. It will help us scaffold our Svelte project. In your terminal, add degit
globally using the command below.
npm install -g degit
Next you need to ask digit
to get the Svelte template and add it to a new project.
degit sveltejs/template svelte-blog
In the command above, the new project is created in a directory named svelte-blog. Open up that directory and take a look at the files.
A couple of things may stand out to you. In the package.json file, we see references to Rollup instead of webpack. That’s because Svelte is authored by Rich Harris, who also wrote Rollup.
If you’re not familiar with Rollup, it’s similar to webpack, but more commonly used in libraries. For example, React, Vue and Angular all use Rollup in their projects. For this site, however, I’m going to use webpack, but switching that out will come in a later article. For now, Rollup works great.
Now, let’s get this app fired up and deployed.
Update Dependencies and Install
You may also have noticed that the Svelte app includes a serve
package. This is a nice, lightweight http server option, but I prefer Express for production. So the first thing I’ll do is install the dependencies and add Express.
npm install && npm install express
Add server.js
Now I need to add a server.js file to the project. This is almost the exact same file added for Vue, except it’s pointing Express to the public directory instead of dist. Here’s the Svelte version of the file:
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
const port = process.env.PORT || 5000;
app.listen(port);
console.log('server started ' + port);
Line 5 is the only change. And just like in the Vue example, this file is in the root of the project.
Update package.json
In order to use Express instead of serve, we’ll need to update the package.json file. In this case we simply update the scripts inside package.json with the exact same command used in the Vue version of the app.
"start": "node ./server.js"
OK, we have both a build and a start script, let’s deploy to Now. Again, the command is simply, now
.
Here’s the URL of the deployment for this first step in building a Svelte-powered blog. You can see the code in the GitHub repo.
Observations So Far
First of all, both of these frameworks are pretty easy to get started with. In the case of Vue, however, we have more provided by the CLI. The Vue app has state management, routing, CSS preprocessing, PWA and linting already set up. That’s pretty great.
On the other hand, open up DevTools and take a look at the size of the files each app generated. The total gzipped weight of the JavaScript for the Vue app is 43.9KB. For Svelte, it’s 1.56KB. That’s not a typo! The bundle for Svelte is under 2KB! Granted, there isn’t routing or state management added yet (beyond component state), but this is still very impressive.
For those of you that are familiar with these two frameworks, you may be wondering why I didn’t use Nuxt.js or Sapper, two full-featured frameworks built on top of Vue and Svelte respectively. They both include support for all the goodies listed above (PWA, routing, etc), and then some.
Those are both great options, but they do too much. I’m trying to explore these two frameworks, and so I want to dig into things to deepen my understanding. I don’t want so much provided for me out of the box. However, if you want to get started quickly, consider giving them a try.
That’s it for part one! In a few weeks I’ll share part two where we’ll focus on setting up server side rendering.
If you liked this post, sign up for my weekly newsletter. I curate the best JavaScript writing from around the web and deliver it to readers every Thursday. The sign up form is right below this article.