Server Components with Bun


An early look at using server components via Bun’s new bundler, with and without React.


My name is Jared and I'm the creator of BUN. BUN is a modern all-in-one javascript runtime environment. It's designed to start fast because it has the edge in mind. It's designed to achieve new levels of performance by extending javascript core, the engine. It's designed to be a great and complete tool, which means it combines a bundler, a transpiler, a package manager, and a runtime.

The runtime is designed to be a drop-in replacement for node.js. BUN installs npm packages 20 times faster. What this means is it's actually creating a new Node modules folder and this is designed to be compatible with node.js. So you can use BUN install in node.js applications without using BUN's runtime.

BUN run starts package.json script 30 times faster. A lot of that is because we take really fast native code and we use that to parse your package.json and the rest.

And in BUN build, in BUN v0.6, we introduced BUN build, which is a new javascript and typescript bundler. A BUN build has built-in support for server components. server components let you use top-level, await, and react components that run on the server. And you can use RPC, where that lets you mix and match server-side code and client-side code. And it'll call those functions and through transpiler code splitting, it will make network requests and really easily run the code on the server without having a whole api.

From BUN's perspective, use server is mostly just code splitting. There's no react in this transform.

I'm going to show you a quick demo of server components in BUN. So I'm going to refresh the page, and you can see just real quick there, you saw it said awaiting child, acing child component, and then it transitioned.

What that did, so we have the suspense fallback. We're rendering the server message function, passing it wait, and we're calling sleep. We're using await inside of a component. Like it's any other javascript code, you can do that with server components. And this code is run on the server.

If we look in the response, we can see that there's no page for server. There's no page that says, hello from server. It's actually in the network. If we look in here in this html string, you can see right there, it says hello from server. So that's being streamed on the server. And then if we go back, we can call functions on the server. If we call get server timer, we can see that we're passing it the greet function. And if we look in the greet function, we can see there's this use server directive. The idea here is this makes it a code splitting boundary where funcs.ts only runs on the server. And it gives a special annotation to these functions that lets you call this code on the server. So if we look at button, we can see from button's perspective, which is a use client component, it's only run on the client. We can just use top level away, and it will call this function, which is on the server, from the client. And you can still use state and the rest of react inside of these client components, because these are fully executed on the client and not on the server. So the idea here basically is it is a really easy way to do RPC with client, which means it lets you call functions on the server from the client. And if we look at the code that's generated here, and yeah, this is a little bit messy. There's a stupid bug I haven't fixed in this, where it's adding two at the end of variable names. But we can see that there's actually no react in any of these imports. This is react, but that's because this is from using JSX. But the actual server components part, which is right here, there's no react in that. The way this works is if we go to... I think this is the right file. No, that's not the right file. If we go to... Nope, not that one. This file.

We can see that we are overriding the imports using Bun's plugin api to load from a manifest generated in Bun build to know what exactly... What each of those client and server imports resolve to. And so as part of Bun build, we output this components manifest. And that is a list of all the server and client components bundled in a build. And this is all stuff that... We're going to release it better. This is a very... What you're seeing right now is very work in progress demo. This is not clean code. We're going to have a project that... A repo that has a much better demo app than this, that is closer to something that people might actually use. But the end result is that you can run code that renders... That seemingly renders react or any other library with the right integration from a server and mix and match client code in there too. And the end result is you get less javascript you send to the client. Because there's no... Because you can have code that... Where it only serializes the result instead of serializing everything. And I think that's really exciting.

8 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