How Bun Makes Building React Apps Simpler & Faster


Bun’s builtin JSX transpiler, hot reloads on the server, JSX prop punning, macro api, automatic package installs, console.log JSX support, 4x faster serverside rendering and more make Bun the best runtime for building React apps



My name is Jared, and I'm going to talk about BUN. BUN is a modern all-in-one javascript runtime environment. It's designed to start fast, to achieve new levels of performance, to be a great and complete tool, and to be a drop-in replacement for node.js. BUN dev is a front-end dev server that starts in four milliseconds. It's a command that's built into BUN. BUN install is an npm package manager, and it installs npm packages 20 times faster than any other npm client that exists today. BUN run is an npm package JSON scripts runner, and it starts package JSON scripts 30 times faster than npm. In BUN v0.3.0, we added automatic npm package installs to BUN's javascript runtime. That means you can just import packages and they install. There's no—you don't have to actually run an install step. This is automatically enabled when there is no Node modules folder. So it still works with Node modules. It just means when you don't have Node modules, if you have a quick script that you just want to run and you don't want to have to deal with installing packages, it just works. The other thing that's really interesting about that is you can—you don't—because you don't need a Node modules folder, you can just—it saves a lot of disk space, and it saves you a lot of time because you don't have to spend this time installing the packages. It uses a shared global cache. In BUN, JSX is natively supported. There's an automatic JSX slash typescript transpiler. JSX is even enabled for.js files, by the way. And you can also have npm packages which use JSX, and BUN will just automatically transpile it. You can console.log JSX. You can do JSX prop punning. And we have extremely optimized react server-side render. This is what it looks like when you console.log a JSX element in BUN. You can see that instead of printing the object representation with the symbols and all that stuff, it actually just pretty prints it like html a little bit. You can see that it still preserves like this is a function or like this is a—it highlights the component to be blue instead of green to indicate that it's an element versus a component. And then this is what JSX prop punning looks like in BUN. There's more than one name for this, but the basic idea is that instead of having to type—if the property name is the same identifier as the value, you can just omit the value. And so that way it's the equivalent of object destructuring syntax, but for JSX. I don't think there are other tools that support this yet. In the next version of react, they're adding a new BUN streaming server renderer. And that helps make BUN three and a half times faster at server-side rendering compared to when using the server.browser build, which is the one that BUN currently uses. Overall, this adds up to four times faster server-side rendering in BUN compared to Node. This benchmark here is a Hello World benchmark for a very simple react app. If you've used any framework in the past, you've probably—for building front-end stuff with react, you've probably used hot module reloading. Usually hot module reloading is something that exists on the client. It's run in browsers. But in BUN, BUN has built-in support for hot module reloading on the server. So here's a quick demo. So this is a page that's already loaded. This is running on the server. It's actually reloading the whole page on the server here. We have it do this hot reload as I type. You can see just how fast this is in the video here. I'm typing and it's immediately reloading. And that's what it looks like. You can see that it's using render to readable stream, the react api, to render this react component. You can also see that it's doing JSX, but it's a JS file. We have a little WebSocket here to send over the new styles, which WebSocket server is also built-in support in BUN. This is an api for sending a file in BUN. So that's a little bit about BUN dash dash hot. Today's priorities with BUN. BUN's runtime is not stable yet. That's really our main focus is getting BUN to be stable. Our second focus is to improve node compatibility. We're doing both of those at the same time. And the goal there is to make it so you can run virtually every npm package in BUN without making changes specific to BUN. We also don't have great documentation or examples yet. Our current documentation is one really long readme. It's probably the longest readme you've ever seen. And the good part about that is it means you can do command plus F to search pretty much all of BUN's docs really quickly, but it means that it's not very easy to browse. So we need to fix that while still preserving the command plus F searching. We also need to add a few missing features to BUN install. It's missing workspace support. It's missing Git support. Those are really important for a lot of projects. What's coming up is we're going to be adding AST plugin api. We're going to be adding native Windows support. Currently we support Windows subsystem for Linux. That works great, but it's a better experience to use the actual Windows. Today our bundler and minifier is not production optimized. There's no minifier, in fact. But we need to build that. The other thing that we need to help with is make it easier to deploy BUN to production. So that's sort of the next steps. Here's a little bit about the AST plugin api. The idea here is you can add bundle time, execute arbitrary javascript, and embed it into your code. So here we have Moment running at build time. And as you can see in the transpiler output, you can see it returned the exact time without actually rendering any. And that's just inlined into the code. There was no extra network trip there. Another thing you can do, BUN has a built-in transpiler api. And this is a test in BUN's code base that lets you embed. So BUN's transpiler api lets you embed javascript objects into the transpiled result. And it will do some dead code elimination to only include the part that you actually used. So you can see there's a big JSON object we're sending over. And it just, and it only actually embedded the URL. It didn't embed the entire JSON object. This means you can inline data at bundle time. So here's another example where we have a bunch of rows of react components. You can see this function. And in the output, it actually just takes all the rows there. This saves a network call. This is what a relay plugin looks like using BUN's AST api. We have the import statement. We inject the import statement into the top of the file. And we have an identifier here that we insert, which is the graphql function. It's still really early for this AST plugin api. We're probably going to make a few more changes to it before we add documentation and start having more examples. But the idea is that you can have bundle time javascript execution. And we think it will maybe inspire new javascript frameworks.
10 min
05 Dec, 2022

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