Vite is a frontend build tool powering the next generation of web applications.
Check out all of the work Evan is doing at his company VoidZero.
For more on the origins of Vite, watch the newly-released Cult.repo’s documentary.
If you’d rather hear Evan talk about Vue.js, listen to the podcast we published with him earlier this summer.
Today’s shoutout goes to user dbush for winning a Populist badge on their answer to How does printing a union itself and not its member work in C?.
TRANSCRIPT
Ryan Donovan: Datadog delivers full-stack observability with AI-powered insights so you can see across your apps, infrastructure, and services, all in one place. Spot issues faster, reduce downtime, and free your team to innovate. Start your free two-week trial today at datadoghq.com/stackoverflow.
[Intro Music]
Ryan Donovan: Hello everyone, and welcome to the Stack Overflow podcast, a place to talk all things software and technology. I'm your host, Ryan Donovan, and today we are talking about Vite and returning to the program, we have Evan You, the creator of Vite and Vue, to talk about what it is, the journey, and the documentary that just premiered at Vite Con. So welcome back to the show, Evan.
Evan You: Yeah, great to be here again.
Ryan Donovan: We've already done the intro stuff last episode. Folks can get to know you there, but I want to get to know Vite a little bit. The idea of a build tool for the web, certainly for a dabbler like me, is– I wouldn't say hard to understand, but it seems like a new concept. Can you talk about why the web needed a build tool?
Evan You: This kind of goes way back, because I started doing front-end more than a decade ago. Everyone started without build tools. It's kind of like you just put the JavaScript on the page, and it just runs. That was the good old days, but then we started building more and more ambitious stuff on the web, right? We started building larger and larger applications. User expectations started to increase on what is acceptable UX on the web, right? So the complexity of the application started to grow, and we realized, okay, like, JavaScript itself– it was not really designed for this serious engineering at the beginning. So essentially front-end engineers started to invent tools for themselves to make things more maintainable. So that involves, first of all, there's the module system. In the beginning, we only sort of– every script shares the same global scope, so you have this global namespace problem. So we started breaking them into modules, but now your source code lives in different files, different modules. Now you need to concatenate them back together. So that was the initial, like, the very first, what we call 'bundling' in the first iteration – is just simply concatenating all the files together, and we wrap each file in a function closure so that the variables don't leak outside. That's like a poor man's bundler, essentially. But the next step, we're like, okay, but I want to use this thing defining another file. How do I do that? Right? Now you need an actual module system that allows a module to export things and allow a module A to import things from Module B, right? So then there was no standard in the language back then. So people started inventing their own formats. So there were like AMD, CJS – there were actually a few different formats in the beginning. They were all competing 'cause there was no standard body on this. So eventually I think there was quite a bit of usage of AMD. It is runtime. And then Node.js came around, and Node.js picked CommonJS as its module system. So people got used to CommonJS, and now people are saying, 'okay, I want to write my code in CommonJS, but I want to bundle them up so it works in the browser,' right? Because the browser doesn't support modules, now we started having serious bundlers that is able to take your CommonJS modules and actually put them together into a single file, and it still works. So this is the first iteration of actual bundling. At the same time, people started to also invent new syntaxes on top of JavaScript, right? So there were people writing coffee script, and ES6 came around, and people were like, 'we want to use a new syntax, but it's not supporting the browser yet.' So people started writing transpilers that just compiles the new syntax into a format that can run in the browser stack. So, now you have the trans power requirements, you have the bundling requirements; when you put these together, now suddenly we have to actually go through a build step for JavaScript before they can run into the browsers. So, this is why build tools came about, and later on – I think there are still people who are very strongly attached to the idea of, like, 'my code should be able to run without build step,' which DHH is actually very strong proponent of that mindset, and it kind of works in some cases, but you have to kind of just like, go all in on that direction, right? But for a lot of people who are building heavier and heavier apps, going without a build step is just not practical. The Bundler also started to have more sophisticated capabilities, like– there's minification, right? Compress your code so you ship less kilobytes. There's also chunk splitting because, like, if your app gets really big, it's actually not ideal to just ship a single big file. None of them is like too big, and you want it to defer some of them, so it's only lazy loaded when needed. So, this makes bundlers that much more complicated. And then people started having all kinds of dabble plugins, 'cause like, once you have a transform pipeline, people start to go crazy. They start inventing their own, you know, syntax. They have these additional, like, CSS in JS stuff, and then there's TypeScript. So, it is not uncommon for people to transform the same piece of code by like three to four different tools before it actually becomes the final JavaScript that runs in the browser. And then you have to pipe all these things into a bundler that puts 'em all together into the optimized chunks, and then minify them. That's your final artifact. So, just think about the things you need to do to turn your source code into the thing that actually runs in the user's browser.
Ryan Donovan: You know, you compile a binary exe, you have a bunch of, sort of, zipped files as part of your desktop distribution, like– this is the next step in the evolution of real complex software.
Evan You: It also really depends on the case because if you're just writing a really, really, really simple app, you can totally go without build step. Because I work on build tools, but I'm not the kind of person to say, 'hey, you should just, like– build tools are absolutely necessary for every single website.' There are cases where you probably don't need it, but if you're shipping something that's production-grade, if you're shipping something that ships megabytes of JavaScript, you probably want to use a build tool so it's actually properly optimized. It also helps you keep your code base more maintainable because it allows you to break it down into modules, use TypeScript, et cetera. Yeah, so that's the thing about build tools is: it just appeared because we're just building bigger things than we initially imagined we could do with JavaScript.
Ryan Donovan: Yeah. You talked about the sort of early coffee script transpiring, and then, you know, people are going crazy afterwards. Do you feel responsible for the sort of explosion of frontend languages transpiled to Java?
Evan You: I'm definitely not the first person to require you to build your files to run. If anything, I work on Vue, right? We do have a thing called single-file components – it's the .vue file, which does require compile step, but you can actually use Vue without build step. That was how Vue worked since version 0.x, and it still works today in Vue3. You can just pull a UV in from a CDN, you can write your template directly in the HTML, and it can actually just work on the fly.
Ryan Donovan: But at some point, if the .vue file or the Vue program gets a little too big, you need to build step. So are you solving your own problem?
Evan You: I would say I definitely participated in that process, but you know, other people built things like Babel, like Webpack, like, I used those things back then. We actually built the first version of Vue's whole build system on top of Babel, Webpack, and all the other things people wrote, because for the most of the time before I created Vite, I was just focusing on the framework side. So, I'm more like a consumer of the actual build tools.
Ryan Donovan: And I wonder about, you know, the feedback loop, whether having a build tool meant you could have new things in Vue, and then having these new things in Vue meant you had to change the build tool.
Evan You: Yeah, there's definitely an element in that, because I created Vite, initially, out of the frustration when I was dealing with Vue's own build tools. We created all the initial versions of those build tools with JavaScript, because that's what JavaScript developers do. Like, JavaScript is probably the only language we're mostly comfortable and proficient in. So we're like, 'okay, let's solve our old problems. Let's build a compiler using JavaScript that compiles JavaScript.' It turns out it worked, but if you compare it to, say, a compiler that's written in native languages like C++, or Rust, or Go, the performance is just very, very different.
Ryan Donovan: I mean, JavaScript doesn't go down to machine codes. It's not a super-optimized language.
Evan You: Modern JavaScript engines, they do a lot, right? There is a lot of very, very advanced optimizations in there. So, in some cases, very, very well-tuned JavaScript can actually run as fast as native code in these engines, right? So, the engine is just able to optimize down to the smallest number of instructions, but due to the dynamic nature of it, when you write an actual compiler with it, when you have, like, AST and you're moving those around, there's only so much the engine can do. It just falls short.
Ryan Donovan: Now, just looking at the website, it looks like a much more flexible, complex system. It's got plugins, it's got a whole thing. I think I saw a quote in there by Rich Harris, creator of Svelte, that it's like the United Nations of JavaScript. What is the complexity, or tooling that it's grown into, and sort of, around that United Nations of JavaScript quote.
Evan You: So, I initially created Vite just for Vue. The very first iterations of it, I hard coded all the Vue compilation logic into Vite itself, in the prototype. I got it working just to see if the whole mental model works, and it turns out to be working quite well, and then I started looking into, 'okay, how do I turn this into a production build?' And then I started thinking about, like, how do I support, say, other things like TypeScript, or like CSS. And I realized, 'okay, there probably should be a plugin system, but the plugin system needs to work for both development and production.' The initial idea was actually an HTTP server, okay? So the build step – we're used to bundling, but Vite started without bundling at all. You would actually write code that says, 'import a .vue file,' or you just import a TS file. That actually gets sent as an HTTP request to the dev server, and the dev server will find the .vue file, and just compiles it on the fly into JavaScript, and sends it back. And all of this is just relying on the Native ES module support in the browsers, which was relatively new when I started working on it. This idea turns out to be working well. That's the additional things I was excited about. Then I started looking at production build. I'm like, 'ah, we still need the bundler,' because for production, you can't just ship all these modules – it'll just be too slow to load. Then I think about the plugin problem. Now, I realize I need a plugin system that works both for the bundler and the dev server. At that time, I noticed a project called WMR that's created by Jason Miller, who is the author of Preact. It had this idea of what we call 'rollup plugin container'. Essentially, it's a simulated container that is able to run rollup plugins without actually running rollup itself. So, we can use that in the dev server so we can support the same set of rollup plugins, both in the unbundled dev server and in the actual rollup bundler. So, that kind of showed me, 'okay, this is how we wanna do it,' but it was very different from the first version of Vite that I created. So, at that time, I already got Vite to like 1.0 RC or something. I was like, 'okay, we can't ship this. We have to rewrite it with a new plugin system.' So, we completely rewrote it for Vite2. Yeah, so I spent another three months just working on the rewrite. Then we shipped Vite2. So, practically, we never shipped Vite1.
Ryan Donovan: Are the plugins essentially like separate containers communicating to the central server?
Evan You: So, essentially, the container is really just a JavaScript object that is able to put the plugins together, run their hooks as they're designed to in rollup; it lives inside the dev server. So, when a request comes in, it goes through the plugin container, the container will apply all the plugins to the source file of their request, and eventually it becomes a JavaScript after it exits the container, and then we send that back to the browser.
Ryan Donovan: Yeah, I'm always interested in how people design absolutely flexible plugins, because you have to anticipate almost anything, or create a very narrow standard for people to apply to.
Evan You: We have to give a shout-out to Rollup and Rich Harris here 'cause he created Rollup, he came up with Rollup's plugin interface, which is what Vite inherits and builds on top of. And Vite was able to get off the ground really fast because we were able to leverage the existing plugin ecosystem of Rollup. A lot of the Rollup plugins would just work with Vite out of the box. So, we just kind of skipped this, like, ‘growing an ecosystem from zero ’ kind of problem.
Ryan Donovan: Yeah. You have a built-in ecosystem there, right? I know you didn't wanna take credit for the explosion of frontend languages, but do you think Vite has enabled new ways of developing web apps?
Evan You: I would say, just in general, I think the biggest contribution of Vite is we showed people how fast hot module replacement can be. So, people start to kind of take it for granted that if you're doing web dev, you save a file, and the change should just reflect instantly on the page. I think that was what attracted a lot of people to Vite in the first place, because– also credits to Webpack, because Webpack was the first thing that came up with a concept of hot module replacement. What it means is: when you save a file, you're able to hot update the component you are currently editing without reloading your page, so the application state is preserved, but your component—that specific component—is updated. So, you're like, swapping it out. That's hot replacement. That was like magical for front-end devs. But the downside of web implementation is that the performance of its hot module replacement kind of deteriorates as your app gets bigger. When people have massive apps, even if it's a hot update, it can take seconds. So, that kind of starts to mess with your feedback loop and just breaks your flow. So, Vite's hot module replacement is 0-1, I would say, so it's essentially de-coupled from the size of application. So, no matter how big it is, if you added a file and it's hot module replaceable, it's almost always instant. So, that's what people really liked because it just allows you to stay in the zone when you're just, like, changing the component really, really fast, very, very frequently. Even though you technically have a build step, when you're editing the component, you don't actually feel like there is one, because everything just updates instantly. So, it kind of makes the build step invisible during development.
Ryan Donovan: Yeah, that is really interesting—the hot module replacement. I think, you know, early days, the application, whatever HTML page, JavaScript... it all lived on your client computer, on your browser; and to be able to change it from the server is super interesting. And I'm curious about what the difference is between the webpack and your version, because I could imagine, you know, when you do that replacement, you have to check to see what else you're breaking on the page, right?
Evan You: Also, credits to Webpack because it designed the hot module replacement API, which our implementation kind of references. Obviously, there are differences now, but the original idea came from there. It has this concept called a hot module replacement boundary. Essentially, you do have to instrument your code a little bit to indicate, say, 'this module is an HMR boundary,' which means when it's dependent files—files it is importing, has been modified—the change will bubble up, propagate to the boundary, and it'll be intercepted. So, everything beneath that boundary can be hot moduled, like, 'swapped', essentially. So, you basically have to make sure, like, when you declare a hot module replacement boundary, it ensures there's no tricky state problem that would happen, right? But luckily, in most component-based frameworks, like React or Vue, it is actually pretty safe to assume every component is a hot module replacement boundary. So, that has worked really well in practice, and both React and Vue kind of just do that by default, so users actually don't have to manually declare the component to be a boundary. So, when you edit things, it would kind of just work. But if you're really advanced, you can declare your own hot module replacement boundary, use advanced APIs to hot swap things that traditionally is not hot swappable.
Ryan Donovan: So what would that be? Would that be like individual strings or something?
Evan You: For example, like if you have a state management thing, you know—global state management thing—and you break it, there may be submodules. You can actually, like, declare these submodules to be hot swappable. So, you can edit some business logic in your state management code and it will be hot replaced. So, when you edit them, you don't reload the page, but when you click the button and it sends requests, and hits that logic, it's actually the new logic that's being swapped in.
Ryan Donovan: Interesting. The code that manages state – that seems like it'd be very tricky to pull off without breaking something.
Evan You: Your code should follow the best practice, where it's like kind of top-down. So, lower nodes in your tree should not be able to pollute state upwards, right? So, if you follow that principle, each bar can be reliable, but yeah, it's tricky.
Ryan Donovan: I wanted to ask: does having a sort of 'build and bundle' step – does that provide any sort of security to the JavaScript? Like, it was all on the page and you could sort of copy and paste anything you wanted.
Evan You: Well, this is only during development, so it doesn't really affect the code you ship to production, so it doesn't really make a difference there. We actually have some interesting security-related issues because when you have an unbundled dev server, you, by default, serve all the files under the current directory, and sometimes users would expose the dev server directly over the network. They would expose it to their local network so they can, like, test it on their phone. I know some use cases where people actually have a Vite dev server running on the server and just like, expose the page across network to the users. You can totally do that, but then you have to be careful because by default, the user will be able to just visit any file under the route directory of your Vite app. So, if you have say, like, an M file that contains your tokens in there, that can be tricky. So, we have added features and, you know, options to have a safe default, so you kind of have to explicitly allow certain files to be exposed. Yeah, most of Vite's related to CVEs, in the past, people reported are related to this, but we've patched all of them over time.
Ryan Donovan: Yesterday—of this publication—was the Vite conference, and premiered a documentary about Vite. The Cult.Repo that made the documentary – they connected us. Tell me how that documentary came about.
Evan You: Yeah, so, it is actually produced by the same director that made the Vue documentary, which was, like, quite a few years ago. I think they were working for a company called Honey Pot back then. So, one day they emailed me and said, 'hey Evan, we're looking for new ideas for documentaries. What should we make?' I was like, 'yeah, make one about Vite.' And we got really excited, and we started just thinking about the idea, and that's how it came about.
Ryan Donovan: Yeah. That's awesome. That must be both incredibly gratifying and a little bit intimidating to have multiple documentaries about your work.
Evan You: It is, it is. In a way, I intentionally want to tell them, like, 'I don't want to make the film about me,' 'cause Vite and Vue, they are both projects that have grown beyond their creator. They are communities now, right? So, the documentary should be about the people behind the project, the community, the ecosystem, people who are involved in the growth of the project – that's really important. So, that makes me a bit more comfortable.
Ryan Donovan: Yeah, I mean, during this conversation, there have been many times where you're like, 'I gotta give credit where it's due, I gotta shout out this person.' You have a shout at this technology, which is very nice to see somebody who's whose work is pretty widely used to be humble and gracious and be like, 'everybody takes credit for this.'
Evan You: I think that's, you know, important in open source, because inevitably some of the ideas you're using comes from someone else, and there might be like layers of inspiration chain somewhere, right? So, just gotta give credit where it's due.
Ryan Donovan: That's an interesting thing about open source is that, you know, you create something and eventually if it takes off, it's not entirely yours anymore.
Evan You: That's also true.
Ryan Donovan: Was that ever a difficult adjustment – having other people sort of guide it?
Evan You: Not really. In a way, like, I do retain as much control as I feel I should have, but in more cases, it's a relief to see someone else who can actually step up and kind of take part of that responsibility off my shoulders. It's actually a good thing to have capable people joining the project and then just like, do their thing.
Ryan Donovan: Was there ever a feature request, or a PR, or something, oh you were like, 'I dunno about this,' but then realized that it was right, or had to sort of fight your own ego?
Evan You: I don't think there were these kinds of things that I don't like, but eventually got in. But like, there is a thing in Vite called the Environment API, which is like, almost entirely team-driven. It was just the combination of ideas from Mathias, Vladimir, Anthony—they actually had this like mini Vite team offsite in Europe without me, and they just had a bunch of people—they were all in Europe, so they were like, 'yeah, let's meet up.' They went to this farm in, I forgot which country it was, but they went somewhere in Europe. They're on a farm, they just like stayed there for a week, and they cooked themselves, and they just had all these crazy idea exchanges. At the end of it, they were like, 'hey, we came up with this new thing called the Environment API. We think it's gonna be great.' The initial few iterations of it was pretty complex. It's a pretty involved concept. So I actually had a bit of trouble just fully understanding what it was about in the beginning, but I was like, 'that sounds useful. Go ahead.'
Ryan Donovan: That's great. That's interesting, where it's like they brought you this thing and you're just like, 'ah, I don't know, I don't understand it, but let's do it.'
Evan You: Eventually, I had to kind of understand what it is to eventually agree to merge into it. But I have to admit, in the beginning, I was like– a lot of things were kind of fuzzy to me 'cause they just like, talked through all of this face-to-face during the time together. I just knew about it after they had this 'walls of text' proposal, and I was like, 'wow, guys, this is a lot.'
Ryan Donovan: Yeah, you didn't get the whole context. So, we've talked a lot about Vite's history. Where is Vite now?
Evan You: For those of you who don't know, I started a company called VoidZero, and we essentially hired a lot of open source contributors to Vite, Vitest. We also work on the Rust JavaScript infrastructure tools, Rolldown, and Oxc. We're trying to get Rolldown and Oxc into Vite so we have a vertical stack that's fully Rust-powered, extremely fast, and performant, and has more features. And on top of that, we are building this unified tool chain called Vite Plus: imagine Vite but more capable. It comes with not just Vite dev and Vite build, but also Vite linked, Vitest, Vite format, and it caches things intelligently in motor repos. A single dependency for you to just start shipping. We are still working on it, but it's gonna be available in the near future, so stay tuned. You know, the Vite documentary – a lot of the stuff we talk about here actually is in the documentary. It's very well made. At this time, it should already be on YouTube, so go check it out.
Ryan Donovan: Well, ladies and gentlemen, it's that time of the show where we shout out somebody who came on to Stack Overflow, dropped some knowledge, shared some curiosity, and earned themselves a badge. Today, we're shouting out the winner of a populous badge: someone who came on to Stack Overflow, dropped an answer that was so good, it outscored the accepted answer. Congratulations to 'dbush' for answering, 'How does printing a union itself and not its member work in C?'. If you're curious about that, we have the answer for you in the show notes. I'm Ryan Donovan. I edit the blog, host the podcast here at Stack Overflow. If you have comments, concerns, topics, et cetera, email me at podcast@stackoverflow.com. If you wanna find me directly, you can find me on LinkedIn.
Evan You: And I am Evan You. I am the creator of Vue JS, Vite, and I'm also the founder and CEO of a company called VoidZero, where we build unified tool chain for JavaScript. Vite is at vite.dev, VoidZero is at voidzero.dev, where the zero is spelled out.
Ryan Donovan: Alright. Well, thank you for listening, everyone, and we'll talk to you next time.