Vite is a build tool that significantly improves the front-end development experience. You can use Vite to set up a development environment for frameworks like Vue and React, and even for a vanilla JavaScript app with a dev server and hot reloading in just three commands.
With no extra configuration, you can also use Vite for TypeScript, and with one additional command you can use it for Sass. (That would take a lot of config for a webpack project. You’d need to mess around with loaders and separately install the webpack dev server.)
Once you have Vite installed, you’ll have a build tool and dev server and be ready to start working with the latest tools and languages.
In this introduction, you’ll learn how simple it is to get up and running with Vite. You’ll also learn about how fast Vite is, how to take the first steps towards using it with a library such as Vue, and how much it gets out of your way when you’re using it.
Fun fact: the name “Vite” comes from the French word for “fast”, which is pronounced “vit”.
How Vite Works
Vite follows a recent trend of tools like Svelte (where the framework is basically compiled away) and other tools like Snowpack that leverage modern JavaScript features (such as ES modules) to provide a smooth, fast dev experience with little to no configuration and not much overhead in the way of installed packages. You basically install Vite with a plugin or two, do very little configuration, and just start working on your app.
Vite provides a modern dev environment that can forego the bundling step because it serves the browser native ES modules. It provides templates (a set of starter files) for a number of frameworks and vanilla JavaScript, and also offers TypeScript, JSX and Sass support (although you need to install one dependency for Sass).
Vite is really fast, because it leverages native ES modules and doesn’t need to rebuild the whole bundle when something changes. This makes HMR updates consistently fast, regardless of the size of your application. When bundling for production, Vite ships with a pre-configured build command that bakes in many performance optimizations out of the box.
As well as being fast, Vite also offers hot module replacement (meaning you see the code refresh in the browser as you develop), and you can use it to compile a minified version of your project to serve in production. By using it, you can get up and running very quickly with a Vue or React project without the buy-in to the Vue CLI or Create React App, both of which ship with the kitchen sink included. This makes it ideal for quick prototyping and smaller projects, although there’s nothing stopping you from using it in a larger project either.
So, let’s take Vite for a spin and see how we go. It will be interesting to see how much of our normal workflow would be better handled with Vite. (Spolier: I found some things were better with Vite, but not everything.)
The First Installation
Let’s get started by installing Vite.
Note: to follow along with this guide, you’ll need a copy of Node installed on your machine.
After running npm init @vitejs/app
, we get to choose a project name and a template. At the time of writing, the options are:
vanilla
vue
vue-ts
react
react-ts
preact
preact-ts
lit-element
lit-element-ts
svelte
svelte-ts
For now, let’s go with vanilla. This generates a directory (based on the project name) with some files in it. There’s an index.html
, main.js
, style.css
, favicon.svg
, and some files for npm and Git. The package.json
only contains vite
as dependency and some scripts to start the dev environment and to start a build.
As the onscreen instructions say, we’ll need to change into the project folder and install the dependencies:
cd vite-project
npm install
We can then start the dev server with npm run dev
and view our app at http://localhost:3000/. Editing any of our project files sees the changes reflected immediately on the screen.
Running npm run build
compiles the project into a dist
folder, where the JavaScript and CSS files can be found. Both files seem to be minified.
The documentation states that TypeScript files are supported out of the box. So although the vanilla
option doesn’t have a dedicated TypeScript template, we should be able to rename main.js
to main.ts
and Vite should compile that automagically, right? Yes, it does! After renaming the file and adding some TypeScript-specific syntax, it all seems to be compiling well.
Let’s try the same with CSS by renaming it to style.scss
and add some Sass-specific syntax. The following error is shown in both the console and on the web page:
I do love a (fairly) descriptive error! After running npm install sass --save-dev
and restarting the watcher, we can now use Sass to our heart’s content. Nice.
Normally I’d think about the stack in advance, install the dependencies I need, and spend a ludicrous amount configuring and figuring out why some tools won’t play nicely together. Of course, we still should think about our stack in advance, but being able to switch from JavaScript to TypeScript and from CSS to Sass with so little effort is quite powerful.
At this point I’m stoked, because we can set up a pretty advanced stack in a minute or two. Given that Vite uses an index.html
as the entry point and builds to plain HTML, CSS, and JavaScript, Vite already proves to be a great tool for static sites and potentially Jamstack applications.
Single-page Application
Let’s find out whether we can set up a single-page application. Let’s try Vue!
After running npm init @vitejs/app
and selecting the Vue template, we get Vite, Vue, and a Vite plugin to compile Vue. If we’re building an SPA, we probably want to handle routes, so let’s install Vue Router.
Vite doesn’t seem to be helpful here. We get a plain Vue setup and we’re in charge of what we plug into Vue. After installing vue-router
and configuring Vue to use it, it works. We could also use Vite to create several pages as described on the multi-page app page in the docs, though this requires tweaking Vite’s Rollup configuration.
I did find vite-plugin-vue-router, a relatively new community-made plugin that generates a router based on file paths like we get with Nuxt.
I’m sure that someone will create a Vue + Vue Router + Vuex template for Vite at some point, but I doubt it’ll ever be better than Nuxt. I suppose the same can be said for React and Next.js, and Svelte and Sapper/SvelteKit. These are web app frameworks that are optimized for their respective libraries and for complex web applications.
I think Vite definitely is an option if there’s no battle-tested web app framework for the language of your choice, though it will require some configuration.
Integration with Other Back Ends
Sometimes I (have to) work on codebases that aren’t Jamstack, but which use .NET or PHP as a back end. Theoretically, we could still use Vite to generate optimized JavaScript and CSS bundles. Vite conveniently has a back-end integration page specifically for this purpose.
After following the instructions, Vite produces a manifest file that contains information about all produced bundles. This file can be read to generate the <link>
and <script>
tags for the CSS and JavaScript bundles respectively. All import
s are bundled into main.js
, while all dynamic imports (import('path/to/file.js')
) become separate bundles.
Performance
The Why Vite page is primarily about performance and developer experience. After some tests, I have to say I’m impressed. Really impressed. Vite dev server starts in an instant and with the Hot Module Replacement, every code change is reflected in the browser quickly, sometimes instantly.
Here, I’ve imported a 100kB JavaScript library, added 20 thousand lines of CSS, changed the files types to TypeScript and Sass to force Vite into using the TypeScript and Sass compilers respectively. Of course, there’s some delay after my attempts to slow things down, but it still exceeds my expectations.
Developer Experience
In my career, I’ve set up hundreds of projects with build tools. No matter whether I used Grunt, Gulp, Rollup, or webpack, big and complex projects took me a day or two to set up and make sure all tools and plugins play along. Later on, I’d invest more time in the tools to fix bugs, improve bundle optimization, and improve their build times.
Compared to that, Vite is a breeze. For this introduction, I’ve set up four stacks and slightly customized them in no time at all. Vite takes away the tying together of two dozen tools and plugins. With some great defaults, you may even be able to skip configuration and get to work. This is amazing. I have similar feelings towards Nuxt, and I presume Next.js works in a similar fashion.
Vite allows us to configure its internals, so we can override the configuration of Rollup and various Rollup plugins. This is great if we have specific needs. Personally, I’d avoid customizing it too much so we can trust that the setup works well, which brings me to my next point: trust.
The more tools I tie together, the more fragile it feels. If one component fails or introduces breaking changes, the entire pipeline breaks, and we have to dive into every tool and plugin and their intricacies again to fix it. Vite essentially takes that burden from us, and Vite has a community at its disposal to look into issues. This means we can trust our tools to do their job.
Conclusion
All in all, Vite is pretty cool! It’s a fine addition to the recent trend of tools that simplifies tooling like Parcel and Snowpack. I was surprised to see how easy it is to set up. It takes so little effort, it almost feels like cheating, and I love it.
If you’re going for a front-end framework, I’d probably go for Nuxt, Next.js, SvelteKit/Sapper, or similar instead. These tools not only simplify tooling and speed up development, but they also add a lot of plugins you’ll probably need for complex applications.
Vite is probably my preferred tool if I’m avoiding a framework but do need minified scripts and styles.