Vite is a new build tool that intends to provide a leaner, faster, and more friction-less workflow for building modern web apps. This talk will dive into the project's background, rationale, technical details and design decisions: what problem does it solve, what makes it fast, and how does it fit into the JS tooling landscape.
Vite: Rethinking Frontend Tooling
AI Generated Video Summary
Vite is a next-generation build tool that leverages native ES modules for improved performance. It eliminates the need for bundling and improves hot module replacement. Vite provides an opinionated default configuration while still allowing advanced customization through plugins. It is framework agnostic and can be used for React and other applications. Vite is being adopted by Next.js and Create React App, and integration with Nuxt 3 offers significant speed improvements.
1. Introduction to Vite
Hello, everyone. My name is Evan Yeo and I'm the author of Vue.js and Vite. Today in this talk, I'm going to be talking about Vite, a next-generation build tool that I've been working on earlier this year. Specifically, I want to discuss some of the design tradeoffs involved in creating a new build tool, why we want to do that, and what is involved.
What is Vite? Vite mainly consists of two parts, a no-bundle dev server that serves your source files over native ES modules, and a production bundler which is rollout-based, is pre-configured and produces highly optimized production builds. Why would you want to use Vite over an existing tool? First of all, it's lean and fast. Really fast. We'll see an example soon. Second, it's opinionated with very sensible defaults. It's based on the experience that I've been working on Vue CLI, which is a very widely used build tool for Vue specific projects over the years. Similar to a pre-configured Webpack and Webpack Dev Server setup. It's also quite similar in terms of scope to Parcel. Many common features like TypeScript, JSX, and PostCSS work just out of the box. Despite being opinionated, it's still very extensible. It has a Rola compatible plugin interface that makes it very easy to build on top of.
2. Performance and Overhead
Legacy browsers like IE11 are becoming obsolete, making way for new JS compilers like ESBuild and SWC, which are significantly faster. Vite leverages native ESM by building the dev server around it, eliminating the need for bundling. Native ESM allows for on-demand loading, leveraging HTTP headers for caching, and efficient hot module replacement. However, there is a downside with native ESM, namely the overhead of HTTP requests. Vite addresses this issue by pre-bundling dependencies with ESBuild, reducing the number of HTTP requests and improving performance.
So VEED leverages CHORN1 native ESM by building the dev server around native ES modules. There are many benefits of a native ESM dev server. First of all, there's no need to do any bundling. That's a big chunk of work that is simply not needed anymore. Second, native ESM is on-demand by nature, which means if a module is not loaded for the current screen that you're working on, it doesn't even need to be processed. Third, since modules are fetched over HTTP requests, we can leverage HTTP headers and let the browser do the caching. And finally, most importantly, hot module replacement can be implemented over native ESM in a very simple yet efficient manner.
So we'll see if this gives us big performance wins soon, but I want to be honest with the technical trade-offs here. Native ESM is not perfect without any downside. The main problem that we have faced is the HTTP requests overhead. For example, a dependency like Lodash ES may contain over 700 internal modules. And because native ESM is eager, when you import even just the single method from Lodash ES, the browser will try to request all of these modules that's imported in its entry point. Now, every module request translates to an HTTP request and the overhead just adds up. It creates a network congestion and even on local machines with little to zero latency, this overhead is still noticeable.
3. Performance and Production Build
Veach rewrites imports to dependencies and appends a fingerprint query linked to the project's log file. Source files are re-validated on every request using ETags and the if-modified-since header. The server start is faster without bundling, and dependency bundling with ESBuild provides a significant boost. The first page load may be slower, but subsequent full page reloads are unaffected. Hot module replacement is faster in the native ESM model. Ideas for improving first page load include persistent caching and replacing part of the module processing pipeline with compiled native modules. Bundling is still necessary for production due to performance and caching challenges. Rollup is used for code splitting flexibility and control, despite being slower than ESBuild.
Veach rewrites the imports to dependencies to append a fingerprint query that is linked to the project's log file. So on page reloads, with a strong cache header the browser won't even make a new request unless your log file has changed. How about source files? Since source files may be edited at any time, we have to re-validate with the server on every request. But we can still leverage ETags and the if-modified-since header to make the request conditional as long as the file itself did not change. This ensures performing full page reloads once the module has been processed once.
We do have some ideas on how to make the first page load also fast by, for example, by introducing a persistent on this cache for source files. Another idea that might be worth exploring is replacing part of the internal module processing pipeline with compiled to native modules. As an example, Parsel 2 recently ported its data processing pipeline to Rust and has seen a big performance boost. So there are potential for us to do the same. But both of these ideas are still in the exploration phase. But we are sure that there are a lot of areas that we can still improve in this model.
So now let's talk about the production build. Some may be asking why even bundle for production if we are using native ES modules? Why not just ship these modules unbundled to production? Well, I don't have time to dig too much into the details here. But the short answer is the performance is not good enough by default. And caching, which is the supposed advantage of unbundled deployment, is very hard to get right. Bundling still seems to be the better trade-off that covers more cases. Another common question is if ES build is so fast, why is V still using Rollup? Why don't we just bundle with ES build? Well, the main reason is that bundling user-facing applications has some really different set of challenges compared to bundling a library, which in most cases is just a single file. Code splitting is very important in delivering performance user-facing applications. As of now, in this regard, Rollup is still more mature and also gives you more flexibility, more control over the chunking process when it comes to code splitting. So this is important both for us, to give you automatic optimizations, and also important for users to be able to manually control the final code splitting behavior. So yes, Rollup is slower than ESBuild, but in practice we found that the actual bundling is only part of the total cost of the real-world projects.
4. Vite's Design and Tradeoffs
Another major build time sink is minification. We at Vite in fact support using ESBuild for minification, so you can get slightly faster builds at the cost of slightly bigger bundles, but we still default to Terser because Terser, while being slower, still provides better compression in most cases.
What we get in return by using Rollup in Vite is that we get to do a few things that are currently still hard to do with ESBuild. For example, automatic CSS code splitting. The CSS imported in your async chunks are automatically built into a separate file and are loaded in parallel with the async chunk when they are requested. We also do automatic async chunk loading optimization. When you have waterfalls in your async chunks, we will automatically flatten them for you. You can also do manual chunk split control by using Rollup options. Most of these are not really possible at this moment with ESBuild. That said, Vite is still open to switching its production bungler to ESBuild or something faster in the future if these become possible, which makes the tradeoff worthwhile. Currently we are essentially opting for a slower production build but better performance for end users, which I believe is the right thing to do.
5. Vite's Opinionated Design
Vite provides an opinionated and sensible default, comparable to a preconfigured Webpack setup. While Webpack is highly configurable, many higher-level tools built on top of it address the same problems repeatedly. Vite absorbs the complexity of these conventions, optimizing for the majority of use cases while still allowing advanced use cases through plugins. Vite does not aim to replace Webpack entirely, as there are still cases where Webpack is the right choice, such as module federation. Different tools can coexist and serve different roles in the ecosystem.
Now, I want to talk a bit about another aspect of Vite's design, the fact that it provides an opinionated and sensible default that gets you pretty far out of the box. If we think about it, Vite is essentially functionally comparable to a preconfigured Webpack setup with Webpack, DevServer, CLI, CSS Loader, Style Loader, PostCSS Loader, you get where this is going. This is not saying Webpack is bad. Webpack started as a JS-focused bungler and it had to be barebones by default and be extremely flexible because we had no conventions back then on how these common tasks should be tackled by a build tool when building a user-facing application. So we had to invent these things over time. It is remarkable that Webpack is so configurable that we're able to actually do all of this with it, right? But over time, we've also come to realize that 90% of the higher level tools built on top of Webpack contain a large amount of configuration addressing the exact same problems over and over again. The way we import CSS, the way we expect TypeScript and JSX to just work, the fact that almost everyone has to use post-CSS, right? These have become conventions shared across tools and frameworks, across ecosystem. So Vita acknowledges this. So it tries to absorb the complexity of getting these conventions working out of the box so the end user can focus on the things that actually matter. We also realize that conventions don't always fit every single use case. So V's philosophy here is that we optimize for the 90% happy path. While advanced use cases are still made possible via plugins, it should not be a requirement for the majority of use cases. So it's also okay that V doesn't cover everything. It's not V's goal to completely replace Webpack. There are cases where Webpack is still the right choice. For example, if you need module federation. It makes sense for different tools to coexist and fit different roles in the ecosystem.
6. V's Powerful Plugin System
V's plugin system, known as the universal plugin system, extends upon Rollup's plugin API. It provides power users with fine-grained control over the dev server and production build. Users can add middlewares, custom routes, and modify the HMR pipeline to tailor the development experience.
Now, that said, V still gives power users a lot via its powerful plugin system. So V's plugin system, what we call its universal plugin system, is shared between the dev server and the production build. It extends upon Rollup's very straightforward plugin interface. It's a superset of Rollup's plugin API. With additional capability to control the dev server behavior, you can add middlewares. You can add custom routes. You can also tap into the HMR pipeline. And finally, when a file changes, you can modify how HMR works. So this gives you very fine-grained control over the whole dev experience.
7. Vite's API, SSR, and Shoutouts
Vite provides an API for loading ESM source files in Node.js and offers efficient server-side rendering with HotModule replacement. It can be decoupled in production, allowing for the development of SSR metaframeworks. Vite is built on top of rollup and ESBuild and has been inspired by projects like Snowpack, WMR, and Web Dev Servers. The team is excited about the future of dev tools and improving the web ecosystem. Evan asked about the use of Webpack, with over half of the respondents indicating they use Webpack-based tools. Vite aims to provide a snappy development experience reminiscent of early web projects.
In addition, Vite also provides an API to load ESM source files and instantiate them in Node.js. With module replacement like pre-system validation. Typically when we do server-side rendering with a bundler, we are essentially running two bundles side-by-side, one for the client and one for the server. So when you edit a file, we actually rerun both bundles. But in Vite, on the client-side, we do HotModule replacement over native ES modules, and on the Node.js side, we actually keep the instantiated copies of these modules in memory, and only invalidate the ones that are affected by your code changes. This is almost like server-side HotModule replacement, which is very efficient. And this also makes it very easy to create a performance server-side rendering dev setup with Vite. Now, it can be completely decoupled in production, so you don't have to use Vite in production for server-side rendering. And the result is, we are seeing a plethora of SSR metaframeworks built on top of Vite. There are SvelteKit, Ream, which is a server-side rendering framework for Vue 3. There's ViteSSR and VitePluginSSR, both are framework-agnostic SSR extensions on top of Vite. And we're seeing frameworks like Markel, essentially using Vite, which is actually able to encapsulate a metaframework-like functionalities encapsulated inside a single plugin. So this kind of speaks about how powerful the plugin system is.
OK. So Vite is growing really fast, and we're really proud of what we've achieved. But I also really want to give a shout out to the projects, these great projects Vite is built on top of, mainly rollup and ESBuild, both are great gifts to the community. And also shout outs to projects that have inspired features in Vite, Snowpack, WMR, and Web Dev Servers, and Parcel. There are a lot of interesting ideas in each of these projects, especially for Snowpack, WMR, and Web Dev Server. We are kind of exploring in the same space and we share a lot of these ideas. So shout out to them for inspiring some of the features in Vite. And yeah, so I'm very excited to see this new wave of dev tools. We are excited to make the web ecosystem move forward and improve dev experience together. Thank you. That's all. Bye.
Vite's Performance and Framework Agnosticism
Everything is kind of fast, I really miss that. Vite works in large projects and can handle that kind of scale. Vite is completely framework agnostic, allowing it to be used for building react applications.
Everything is kind of fast, I really miss that. So you'd actually like to go back to that 10% of nothing? Not nothing, right? We kind of want to have a cake and eat it, too. But it should feel like that nothing. That would be great.
So we're going to go to our audience questions now. So if you have any questions, you can still do so in the Community Track Q&A channel.
First question, is there any data already out there for Feats Performance in a large real-world application in production? Yeah. So I just saw this article on dev.to a while ago. Someone migrated a project with 150,000 lines of code. So that's a pretty big code base from I think it was previously Webpack. So they moved to Vite and I'm trying to look at the numbers. So originally, a code start using Webpack was 150 seconds and the app loads in six seconds. So after migrating to Vite, a code start is six seconds and the app loads in 10 seconds. So hot reload went from 13 seconds to one second. And if you put Vite in build mode, the build watch mode is still from 17 seconds Webpack to 13 seconds Vite, so that is actually running a full build on every save. So yeah, I would say you get probably 10 times better performance during dev in this very case. Obviously, it will kind of vary and I think this has a lot to do with how their old Webpack configuration was using probably using full Babel or TypeScript. So they also did compare this by switching from Babel loader to ESBuilt loader for transpilation which did increase the performance by quite a bit. So let's see. So that shaves their speed from 185 down to 56, which is decent, but still not as fast as Vite I would say. So yeah, that's just some anecdotal data, but I think it's a good reference. So I guess the takeaway is Vite does work in large projects and is indeed able to handle that kind of scale.
So if people want to read up on these numbers, can you share this article in the Discord channel? Yeah, definitely. Great.
Next question is from Jean Cartier and he's a bit confused. He says, I don't understand. So we can use Vite for building react applications? Yes, absolutely. So Vite is completely framework agnostic. I originally created because I just wanted to get a faster dev server for myself to use Vue. But as we got closer to feature completeness, I just realized, okay, most of these actually apply.
Vite's Framework Agnosticism
Vite is framework agnostic and can be used for React apps or other apps. The Vue-specific logic was extracted into a plugin, making it suitable for any framework. Vite's fast app server is attracting users from Create React App as well.
They're framework agnostic. They would apply equally well for react app or other apps. So, I managed to just, basically, I did a refactor trying to think, in V2, the biggest thing was we extract all the Vue-specific logic out. And that was also a good process for us to think about the plugin API. Because if the plugin API can help, can allow us to cleanly extract all Vue-specific logic into a plugin, then it should work equally well for any other framework. Because Vue, in terms of the compilation setup, is actually pretty demanding. So once we did that, it proved to be quite successful. We're now seeing Spelt, like a lot of people are switching from Create React App to Vite as well. So, yeah. So, I'm pretty happy about that. Because I feel like we put in all the work building a fast app server. Which makes sense for it to be able to help not just Vue users.
Affiliation with Vue and Vite's Adoption
Do you think being affiliated with Vue might fight against the adaptation of Vite? As long as the tool helps you be more productive, it shouldn't matter who created it. Vite does not provide integrated production build processes like pre-rendering out of the box. However, you can easily do it yourself using Vite's APIs or rely on meta frameworks built on top of Vite, such as Filekit, REAM, and VitePress. Vite is being adopted by Next.js and Create React. The integration with Create React app is still in progress due to challenges with Jest support.
And a follow up for me then, do you feel, do you think that because you are so affiliated in your name and so attached to Vue, that might fight against the adaptation of Vite? Because people think this is a Vue thing, because Evan built it. I don't know. I guess, you know, some people are kind of tribal, but I just think if you're a web developer or an engineer, your end goal is to use the tools to build great products for your end users. So why does it matter who created the tool you are using as long as it helps you to be more productive.
Yeah. Yeah. Yeah. Yeah. That's a great, great view. And I hope people will do that. Look at the best tools and, yeah, just use the best tools.
Next question is from Peru, is VITE gonna have some more integrated production build process out of the box, like pre-rendering? If you look at our repo, we have a server-side rendering example. So that example actually already includes a pre-render script as well. It's pretty simple. We're probably not going to do that out of the box. It's kind of a scope thing, right? So you can easily do that yourself using VITE, but it's not something, because it kind of ties into what framework you're using, how you want to actually deploy it, right? So VITE isn't as opinionated as that. We essentially give you the APIs for you to do it in the way you want. I consider that to be a job of the meta frameworks built on top of VITE. I guess filekit kind of does that, REAM also does that. VitePress is a static site generator that we built on top of VITE. So if you're building a doc site, you can use VitePress, which basically works out of the box.
Nice. Next question is from Jack Burke. When is Vite being adopted by Next.js and Create React happen? Make it happen yesterday please. Thanks. I guess if you're using Create React app, you can just switch to Vite directly. I guess there are some parts of the Create React app stuff that's still kind of missing, like Jest support, out of the box. Jest integration has been a somewhat interesting challenge because Jest does not support async transform and async module resolvers. These are the kind of blockers that I think the Jest team is working on. If they are soft, then it makes it pretty straightforward to integrate.
Vite's Competence and Integration
Vite is a competent CRA replacer. Next is deeply integrated with Webpack and unlikely to switch. Webpack isn't a dead end, but over-configuration can be a burden. Nuxt 3 and Nuxt 2 offer ways to run on Vite, resulting in significant speed improvements.
But at the same time, we have other solutions like Sypress, which can run your component directly in the browser. But other than that, I would say Vite is a pretty competent CRA replacer. Like Repl.it actually just switched over from CRA to Vite for all their React REPLs. And as for Next, that's kind of a different story because Next is pretty deeply integrated with Webpack. They do pretty advanced pre-compiling. So I would imagine it would be difficult for them to actually consider a switch. They also just hired Tobias, who is the author of Webpack. So I think they're pretty committed on that path, but I know they're doing a lot of interesting work to make Next fast as well. I mean, Webpack isn't necessarily a dead end. I think a lot of it has to do with the historical burden where people just over-configure it. But if you can, say, use ESBuild for transfilation, have very, very first-party optimizations out of the box like Next does, you can still get pretty decent performance. So I'm interested to see how this unfolds. I mean, in Vue land, Nuxt 3 is able to be bundler agnostic, so they have a mode that can actually run on Vite. I think Nuxt 2 also offers a way to actually run on Vite already. I've heard people who switched over their current Nuxt project to run on Vite, and it just got 10 times faster in development. So, I think it kind of depends on how these higher-level frameworks work. Yeah. Yeah.
Q&A Conclusion and Farewell
Beginners can go to Vite instead of React. It's more important to show what you've built than the tools you know. Q&A session ends. Evan is available online. Thank you, Evan. Hope to see you again soon.
All right. Last question we have time for today in the live Q&A is from Yatchna. Beginners can go to Vite instead of React. Is that going to help us to improve our resume? I don't know. Vite is just a tool that helps you build stuff. I think it's more important to actually show what you've built instead of showing what tools you know how to use. Right? Yeah. Yeah. I hope so, too, that employers look at that.
All right. That's the end of our Q&A. But if you have more questions for Evan, Evan is going to be on his speaker room. So there you can continue the conversation about anything you want to talk about with Evan. Oh, you don't have a speaker room. Oh, okay. Sorry. Sorry. Yeah. That was my mistake. My mistake. Sorry. But Evan is available online. You can find him everywhere.
So Evan, thanks a lot for joining us. Thank you. It's been an honor having this Q&A session and announcing you. Hope to see you again soon. Thank you. Bye.