Bring Node.js into your browser with WebContainers

Bookmark

In this talk, I'd love to inform and inspire the community to push the limitations of web development running Node.js inside the browser. I will cover how and why we developed WebContainers, what our roadblocks and limitations were and are, how we've worked with the community to make the technology better and what has already been enabled and built with WebContainers.



Transcription


Hello, node.js Congress. Welcome to my talk about bringing node.js into your browser with web containers. We'll talk about the history of Node, about browsers, and finally about web containers. Web containers are a technology from StackBeats that enables you to run node.js apps inside your browser. This is really the very first time that we are talking about that in public, so thank you for having me here. My name is Silvia Vargas, and I'm a front-end developer, but I also run developer relations at StackBeats. So this is the roadmap for the next 20 minutes. First, we'll talk about the early 2000s and the attempts to take javascript out of the browser. Then, we'll move back to the 2020s, where we will talk about bringing node.js into the browser. And finally, we'll take a look at the present times and the future. As you see, this talk really starts and ends with browsers, and so you will see a lot of those in this talk. If you're a person who likes to try things out immediately, go check out Node.neo, which is a disposable node.js playground powered by web containers. Meanwhile, while you are experiencing the future, we will move back in time to the early 2000s. Are you ready? Okay, so let's talk about the story or history of node.js. node.js was created by Ryan Dahl in 2009. You need to keep in mind that javascript was created to be executed inside the browser. In one of his talks, Ryan explained how he was looking for a way to build a network application that could handle a large number of simultaneous requests. So, before node.js, there were some attempts to run javascript outside of the browser. For example, one of such attempts was Rhino, but they never managed to bring server-side javascript to the mainstream. node.js changed that. So, let's look at how that happened. In 2008, Chrome was released with V8. V8 is a javascript engine. It is an open-source project designed to execute javascript code as fast as possible by employing JIT, just-in-time compilation. That means that javascript is compiled to machine code and not interpreted. So, here is the announcement blog post from 2008. We will not read it in its entirety, don't worry, but let's take a look at one fragment. So, no-one likes big quotes, so let's take it apart. Here are some prophetic words. As web applications grow, we believe that Swift will be representative of how web developers write javascript code. Chrome really did change how javascript is written, but also where. And now the second part of the quote. In the second part, here they are mentioning their mind-blowing benchmark suite consisting of five average JS apps. A total of 11,000 lines of code. 11,000. I will leave you with this number. So, in this context, Rayyondal pulls the source of V8 and spends six months on creating node.js. node.js was designed to be an event-driven server-side framework that could handle I-O operations in a non-blocking way. Now, JS could be really run everywhere. And here is a talk from 2009 JSConf where Rayyondal presented this idea. To understand our problems better, the problems that we are facing today, let's take a look at the history one more time, or one last time. How was the internet like back then, back in early 2000s? Back then, the browsers weren't too powerful. So, for example, in one talk, Rayyondal mentions how excited he was about the progress bar when uploading files. Like, just to remind you, this is what the progress bar looked like. I mean... So, fast forward 15 years, and we see that browsers grew in power. Now, we are... Now, actually, let's look at the comparison. So, in 2000s, five average pages were just of 11,000 lines of code in total. Right now, when you run a create react app, that alone generates 30,000 lines. In 2005, that's when Google Maps and Gmail was launched. Now we are talking about edge computing, real-time collaboration, and AI. Back then, the top three websites in 2005 were Wikipedia, Flickr, and iTunes. Or in 2008. Right now, it's Google, Facebook, TikTok. Like, if you look at those three, actually, they are kind of... Those pairs, they are kind of similar, but only in terms of how they are used and not really, you know, the technology. And in 2000s, that was... We need to remember that that was pre-ES5, whereas now we are so many, you know, iterations of ECMAScript ahead. We have the websockets, service workers, and so on. So, given how powerful browsers are nowadays, maybe we could really run javascript, including node.js, everywhere. So, let's talk about bringing node.js to the browsers. The fact that you can do something doesn't mean that you should. So, let's look at what could be enabled with node.js running in the browser. For example, you know, there's a use case of education. From courses to blogs to demos, your audience could just, like, experience what you are teaching them right there in the website. documentation, showing is always better than telling. testing, you know, creating reproductions. Client-side tooling, like bundlers, task runners, and code generators. Employment, like interviewing platforms or onboarding platforms. And finally, experimentations. We ourselves don't know how you can really use web containers to its full power. We'll see. So now, it all sounds great, but, well, there is a but. node.js is designed to work with server-side APIs, such as file systems, network sockets, and HTTP servers. Its big portion is also written in C++, which can't be run in the browser because browsers only speak two languages, which is javascript and WASM. Then, the browser environment is designed to work with APIs, which allows javascript code to interact with user interface, I don't know, handle events, and so on. Browsers are also isolated environments. They are sandboxed. That means that they have no way to, I mean, they can't just access your local machine. This is for security reasons. So, it is clear that there is an api mismatch. So even if you, you know, compiled node.js to WASM, even if they spoke the same languages, that still wouldn't work because they don't have the same tools. So, there are some approaches of solving this issue, right, of bringing node.js to the browsers. One of such examples would be virtual machines in the cloud, running them to execute user code. However popular this approach is, there are some drawbacks. First of all, it's costly. Your users pay per minute of connection and also per storage. And then there's also the environmental cost. Secondly, VMs depend on the internet connection. So, no internet, no service. What if you lose Wi-Fi while working? And third, it's also dangerous. This approach is popular among Bitcoin miners, but also phishing websites and so on. Then another example would be playgrounds that don't rely on cloud, but require custom patching for every single framework. StackVis had one of such playgrounds as well, with a technology called EngineBlock. This approach was not scalable because there are so many different frameworks out there. The most important point though is that it just doesn't emulate node.js. It only emulates its very limited capabilities. Like, you have to provide patching for every single framework. So, what I'm trying to say is that the patching, if any, should be kept to minimum to emulate node.js behaviors to the most accuracy. So, what if I told you that there's actually a better way? Well, in May 2021, StackVis announced web containers. So, just like Randall pulled the source of V8 to enable javascript to run outside of the browser, StackVis pulls node.js from the source to enable running node.js apps inside the browser. So, StackVis emulates the behavior of node.js to run in browser with WASM and with some rust to the highest accuracy possible. So, even though it was announced in May 2021, the web containers were already working well a bit before. For example, here's a podcast episode where Dom and Eric demonstrate web containers. So, how did StackVis actually manage to do that? Well, the story goes back to 2018, actually 2017, where StackVis was just conceived. Before that, Eric Simons and Albert Pye, they were two childhood friends. They were running a platform where you could learn to code. They noticed that their students usually struggled with setting up the environment. So, in 2018, they thought that they would leverage the power of a browser to lower the barriers of learning to code. So, the very first two years were very frugal. It was just them and two engineers, Dom Elm and Tomek Słukowski. So, StackVis was growing the team and also developing web containers. Here's, for example, our team right now. We are in 14 countries. So, let's talk about how, actually, we figured out this innovation. This meant, for example, writing the entire file system, which actually took three iterations until it was finally scalable and fast enough. It was about implementing ES modules, which included, for example, circular imports and how modules were instantiated. Implementing event loop, implementing the V8 serialization api, creating Turbo, which is our own package manager, which actually we are sunsetting right now because we have native support for package managers. And then also figuring out how to run shell commands and how to integrate Git. But working on web containers also meant designing for the future. A future that is sustainable, open and collective. From the beginning, StackVis was about supporting the whole web ecosystem and taking bold decisions about emerging technologies. So, for example, even though the spec for WASM threads has only recently reached phase three in its path to becoming a standard, this technology has been the bedrock of web containers since a very long time, allowing the incredible speed. Here is also a blog post, if you want to read, by my colleague Roberto Vidal. Connected to that, StackBlitz uses shared array buffer, which is a modern javascript feature. It allows for parallel processing and faster execution times. Choosing it meant initial limited support for Safari, but not anymore. In January 2023, Safari was announced with shared array buffer support. And many of the frameworks just work in web containers. For example, here is an astro project, SvelteKit, and of course, Node. We will iron out the details before we make an official announcement. But building for the future also means a commitment to making the whole ecosystem better. Here are some examples of how pushing the browsers to their limits benefited web dev community. So, for example, we detected the recent V8 WASM memory issue, which was a hard limit on number of WASM memories. Here is the issue, and here's a blog post about it. Then we also found a bug in Firefox threads. Here is the issue, and here is a blog post about it. Or how about the ARM issue in M1 MacBooks? Here is an issue, and it's just been fixed. As you see, StackBlitz really pushes browsers to their limits. Because of that, we joined Bytecode Alliance, which is a cross-industry partnership accelerating the world's transition to secure by default computing. But improving the whole ecosystem is not only about spotting bugs. We are also huge fans of open source. On our journey, we submit PRs to the tools we use. For example, WASP pack, parking lot, PMPM, Git isomorphic, or like this one to node.js, which paved the path to universal packages. But we also support vite not only by sponsoring it or sponsoring ViteConf, but also by hiring its core maintainer, who works full-time on vite. All this is to say that we do love open source. In May 2022, we worked with the Speltkit team on making Web Container api so that everyone could use this tool to push the boundaries of the web with us. In February 2023, we released it and it's free for open source as well as small-scale for-profit projects. If you want to learn about it, you can go to webcontainers.io. And on there, you can actually see a small web container running. You can also try it yourself. You can just go to webcontainers.new. So let's see what has been built with Web containers so far. For example, education. Web containers are used in Total typescript, the amazing course. They are used in Docs. For example, an embedded demo from the node.js docs. They are used as back reproductions. They are used in tutorials, the Speltkit tutorial. They are used in experiments. For example, this visual programming app, Nano. Here is also an app that uses AI to generate other apps. And finally, I mean, there's also the client-side tooling. For example, cloudflare Wrangler, that is a tool to develop cloudflare workers. And maybe this is also a good time to talk about how Web containers work. So first, Web Container boots up. This is when an iframe is created in which the Web Container will operate. This is yet another level of security. As you remember, the browser is a sandbox environment. In the browser, there is the Web Container running in its own iframe so that it has no access to any information on the page on your website. So it's double isolation. Then, once the Web Container is booted, dedicated workers come into play. They will function as processes for your program. If you are installing dependencies or if there's any package manager situation happening, Web containers will make requests to a standard domain, which serves as a proxy to package registries, thanks to which the installation is optimized. So usually, actually, the dependency installation goes faster than locally. If it's not, let us know. And if your app features a Web Server, Web containers include a virtualized TCP networking stack that's mounted to your browser's Service Worker api. So if your node.js app runs a dev server, you'll be prompted to open a URL that points to an external domain that is actually powered by a Service Worker locally inside your browser. Because of this connection, you can open this URL in another tab, and it is securely isolated from another browser instance. That also means that even if you lose the internet connection midway, you can still see that this URL works as long as the Service Worker is registered. So Web containers are actually fast, faster than local, because of how we handle dependency. Here is a demo of pnpm, up to four times faster than local, and of node.js. Again, if something takes longer than locally, please let us know. So now to sum up, why would you use Web containers? First, it's a safe way to run code. It's twice isolated. It's a fast way to demo ideas. It's just one URL, and you can code, and then you can share it with someone. It's a cheap way. You don't have to pay to run it or to use it. We have paid plans, of course, but most of our users actually enjoy Stackbrite free. And before I move on to the last part, let's look at the tweet I saw the other day. Well, we all know the pains of stashing, cloning, checking out a branch, running dependency, running dev server. I mean, look at the number of likes. There's just so many people who are relating to this. What if I told you that this is no longer a problem? Web containers make it a pleasure to review PRs and check reproductions. Here is, for example, a PR on Elkzone, which is a very beautiful Mastodon client. On the PR, you can see a code flow at the bot. This button provides an instant and disposable environment. Code flow ID is a replica of VS Code, but powered by Web containers, which means that it runs node.js inside the browser. You get an environment on just one click. If you click on the PR button, you will see the entire environment with dev server running and all the recommended extensions loaded for you. If you want to try it, go to any GitHub repository and just add pr.new to the beginning. In this way, you will join two million devs who use Web containers monthly. And that's it. If you have any questions, find me at Sylvia Vargas or just reach out to me. Thank you for having me here.
21 min
17 Apr, 2023

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Workshops on related topic