2
头图

background

During this time, a JavaScript runtime called Bun (bun), which claims to be able to beat Node and Deno, was born, and immediately caused a stir in the JavaScript community. So how many kilograms and taels does this so-called flying steamed bun actually run? This article will let us use some practical examples to understand the functions provided by Bun and how much faster it is than Node, and finally discuss whether Bun can replace Node.

what is bun

Let's first look at the official description:

Bun is a fast all-in-one JavaScript runtime

Bundle, transpile, install and run JavaScript & TypeScript projects — all in Bun. Bun is a new JavaScript runtime with a native bundler, transpiler, task runner and npm client built-in.

In short, Bun is a large and comprehensive JavaScript runtime .

Not only does it do what Node and Deno do (the JavaScript runtime), but it also 原生 supports the following features:

  • bundler: Bun can package our project like Webpack and other tools
  • transpiler: Transpiling that supports TypeScript/JavaScript/JSX, in other words, you can write TypeScript and JSX syntax directly in the project without worrying about the wrong environment
  • task runner: can run the script script in package.json, similar to npm run xxx
  • Built-in same package management tools as npm: implements the same functions as npm, yarn and pnpm package management tools, but faster

Some students may ask: Aren't these functions supported by the front-end and node ecology now? What is there to learn? In fact, Bun's features are not in these functions, but in 原生 and . Native means that it comes with Bun, and we can use it without writing any configuration files or installing any plug-ins, which reduces the cost and efficiency of our coding. Another feature of Bun is that it is fast, so how fast is it? Look at some official website descriptions:

截屏2022-08-20 上午11.03.43.png

截屏2022-08-20 下午3.30.09.png

The data can be seen from the description above:

  • The server rendering speed of Bun is about 3 times that of Node.
  • Bun runs scripts about 30 times faster than npm run
  • Bun's download package is 20 times faster than yarn

It does sound a bit fast, but what is the actual effect? Then let's actually take a look.

Bun function introduction

This part of the content will introduce the comparison between Bun and Node or other tools in the Node ecosystem such as npm, but will not involve Deno, because the performance of Deno is not much different from that of Node.

Bundler and Transpiler

As a front-end engineer, we often need to use tools such as Webpack to transpile and bundle our code. Unlike Node, Bun natively supports the capabilities of Bundler and Transipler without requiring us to install additional dependencies. In addition to these, Bun also has built-in React scaffolding capabilities, you can create a React application by typing a command:

 bun create react ./react-app

After the above command is run, a project code with this directory structure will be generated:

 react-app
├── node_modules
├── README.md
├── bun.lockb
├── node_modules.bun
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
└── src
    ├── App.css
    ├── App.jsx
    ├── images.d.ts
    ├── index.css
    ├── index.jsx
    ├── logo.svg
    └── reportWebVitals.js

From the above directory structure, the React application created with bun is very refreshing, there are basically no additional configuration files, and the code can be written directly. Most importantly, it only took 6.55s! to run this command on my scumbag computer . In contrast, using npx create-react-app ran a full 四分钟 to create a React project. In other words, Bun can create a React project 40 times faster than npm with create-react-app ! Judging from this speed alone, it's not an exaggeration for Bun to say that he is as fast as lightning.

Although the code generated above only has JS files, but bun supports TypeScript Transpiler natively, so you can write TypeScript code directly.

After the code is generated, we can use the bun dev command to start a dev server listening on 3000 port 带热更新 . The execution time of this command on my computer is 0.3s ! The service has not yet responded. On the contrary, the project created with create-react-app takes npm start takes 25s . Just looking at this case, Bun task runner is 83 times faster than npm task runner.

After you have developed the code, run bun bun this command can package the project, this command will package a binary file with .bun suffix, this command executes about 0.1s , the packaged files can be accessed directly by throwing them into a static server. In contrast, the application created by create-react-app runs npm run build it takes 28s to package, so in this case, the speed of Bun is 280 times that of npm .

It is worth mentioning here that although bun packaging files is more than an order of magnitude faster than using npm to package files, bun does not support common static code optimization methods such as minify and tree-shaking , which are all on its RoadMap. will be supported later. We can only wait and see if it will be so fast after these functions are added.

Develop a web server with Bun

Bun's support for HTTP services is very good, you can write extremely stripped down code to start a web service:

 // http.js
export default {
  port: 3000,
  fetch(request) {
    return new Response("Hello World!")
  }
}

The above code will start an HTTP service on port 3000, which will return a Hello World! string. Use the wrk tool on my computer (Macbook Pro 2.9GHz dual-core Intel Core i5 8GB RAM) to test the performance of this service:

 wrk -t 10 -c256 -d30s http://localhost:3000/

The above command will start 10 threads and 256 links to continuously test our interface for 30s. The final data is:

 Running 30s test @ http://localhost:3000/
  10 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    17.42ms   40.52ms 515.51ms   96.32%
    Req/Sec     2.33k   822.60     4.26k    65.55%
  660630 requests in 30.08s, 57.33MB read
  Socket errors: connect 0, read 3, write 0, timeout 0
Requests/sec:  21963.67
Transfer/sec:      1.91MB

We can see that the QPS of Bun's native HTTP service on my computer can reach 21963.67, then let's take a look at the performance of Node's native HTTP service. The code is as follows:

 const http = require('http')

const server = http.createServer((req, res) => {
  res.end('Hello World!')
})

server.listen(3000, () => {
  console.log('server is up')
})

The above code implements the same logic as Bun's HTTP server, but with a little more code. Using the same parameters on the same computer to test the performance of Node's native HTTP service, the results are:

 Running 30s test @ http://localhost:3000/
  10 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    23.80ms   34.24ms 460.40ms   96.19%
    Req/Sec     1.31k   341.72     2.02k    82.15%
  376228 requests in 30.07s, 46.64MB read
  Socket errors: connect 0, read 58, write 1, timeout 0
Requests/sec:  12513.65
Transfer/sec:      1.55MB

As can be seen from the above results, the QPS of Node's native HTTP service is 12513. From this test result alone, the performance of Bun is about 1.75 times that of Node . In this way, although Bun is faster, it is not too exaggerated. However, this may also be related to the machine, because I looked at the test results of some foreign bloggers, and their computer performance is relatively good. With the same test code, the QPS of Bun can reach 200k, while Node is only 20k. From their results, Bun's performance is 10 times better than Node 's, which is a qualitative leap. So how big is the performance gap between implementing a simple HTTP service with Bun and Node on your computer? Why don't you try it now?

Bun as a package manager

As mentioned above, Bun has a built-in package manager similar to npm. The command to install a package (moment.js) using Bun is:

 bun install moment

The above command is the same as npm install moment , it will install a dependency into the node_modules folder, this command ran on the author's computer for 2.6s , and then let's run npm again:

 npm install moment

On the same computer, npm ran for about 12s . From the speed of installing the moment package, the speed of bun is 4.6 times that of npm . The range measured by foreign bloggers is generally 4 to 80 times, which should be caused by different dependencies and installation times. In general, Bun is really much faster than npm as a package management tool. As for how it compares with yarn and pnpm, it is up to the readers to verify and leave the results in the comment area.

Bun as a React server-side rendering solution

Bun natively supports React's server-side rendering, and the simplest SSR implementation using Bun is like this:

 import { renderToReadableStream } from "react-dom/server"

const dt = new Intl.DateTimeFormat()

export default {
  port: 3000,
  async fetch(request: Request) {
    return new Response(
      await renderToReadableStream(
        <html>
          <head>
            <title>Hello World</title>
          </head>
          <body>
            <h1>Hello from React!</h1>
            <p>The date is {dt.format(new Date())}</p>
          </body>
        </html>
      )
    )
  },
}

Visit localhost:3000 to get:

截屏2022-08-20 上午10.45.00.png

However, most people should not write SSR so naked but use a modern framework like NextJS. Bun also takes this into account, so it also natively supports Next scaffolding. Use the following command to create a Bun Next application:

 bun create next next-app

The above command ran on my computer for 20s , and using npm to run create-next-app ran for 10 minutes. From this speed alone, Bun is 30 times faster than npm .

The above command will create a next application listening on port 3000:
截屏2022-08-20 上午11.00.31.png

We also try to use wrk to test the concurrency performance of this Next application:

 wrk -t 10 -c256 -d30s http://localhost:3000/

During the test, you can see that the Bun application is outputting frantically on the standard output and then crashes! Yeah, it's really broken

 [603.38ms] / - 3 transpiled, 15 imports
[604.97ms] / - 3 transpiled, 15 imports
[613.77ms] / - 3 transpiled, 15 imports
[618.38ms] / - 3 transpiled, 15 imports
[621.86ms] / - 3 transpiled, 15 imports
[623.29ms] / - 3 transpiled, 15 imports
[648.52ms] / - 3 transpiled, 15 imports

SegmentationFault at 0x0000000000000000


----- bun meta -----
Bun v0.1.10 (fe7180bc) macOS x64 21.6.0
DevCommand: fast_refresh hot_module_reloading tsconfig filesystem_router framework public_folder bunfig 
Elapsed: 87754ms | User: 3341ms | Sys: 662ms
RSS: 127.34MB | Peak: 127.34MB | Commit: 67.15MB | Faults: 4894
----- bun meta -----

Ask for #help in https://bun.sh/discord or go to https://bun.sh/issues

I don't know the specific reason, but the official document also said that Bun is only Partial Support for Next, that is, it is partially supported, so we will not delve into the reason. Let's take a look at a Next application running with Node:

The Next application running on Node created by create-next-app can pass the wrk test, and the results are as follows:

 Running 30s test @ http://localhost:3000/
  10 threads and 256 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   922.74ms  200.38ms   2.00s    78.20%
    Req/Sec    30.48     22.34   160.00     80.72%
  7635 requests in 30.09s, 31.90MB read
  Socket errors: connect 0, read 0, write 0, timeout 97
Requests/sec:    253.71
Transfer/sec:      1.06MB

Node's Next application QPS can reach 253. This also leads to a conclusion that Bun has not fully supported the function of Next, and it is very unstable .

Some other functions of Bun

Due to the limited space of the article, all the functions of Bun are not listed here. In general, Bun also has the following functions that are worth exploring by readers:

  • bun:sqlite : Bun's built-in operation for Sqlite database, the performance is also very good
  • bun:ffi : Bun can call any language that supports C ABI through ffi, such as Zig, Rust and C/C++, etc.
  • napi : Bun supports 90% of Node's napi

Why is Bun so fast

From the actual use effect of the author above, Bun is indeed much faster than Node, and then let us explore some possible reasons why Bun is faster than Node.

JavaScriptCore replaces V8

This is the official reason given by Bun. Bun uses Apple's JavaScriptCore engine instead of Google's V8 engine. JavaScriptCore is the underlying JS engine of Safari. Compared with V8, the embedding cost is a little higher. As for whether JavaScriptCore is really better than V8, it is really difficult to judge. I didn't find some comparative data of different JS engines Benchmark on the Internet. Instead, some foreign bloggers actually tested Hermes (produced by Facebook), JavaScriptCore And V8, found that performance- wise Hermes is slightly better than JavaScriptCore and slightly better than v8 . However, it is a little bit worse, which is also related to the test code. If you can have some actual and authoritative test data, please comment in the message area.

Use Zig language

This is also the reason given by the official Bun, let's take a look at what the original words say:

Zig's low-level control over memory and lack of hidden control flow makes it much simpler to write fast software.

It means that one of the reasons that Bun is fast is the use of Zig, a language that has a lower level of control over memory and hides control flow. Honestly, if it wasn't for Bun, I didn't even know the language existed. I Googled this language, it probably borrows some ideas from Rust, the purpose is to improve the C language, and the release time is very short, it was first released in 2016, and now it is not even in the top 50 in the TIOBE language popular list . So I remain skeptical about the language .

the reason i think

To be honest, I think the reasons given by the official website are not convincing enough. In my opinion, it may be due to the following reasons that Bun currently performs better than Node

  • Bun is still immature, and many industrial-grade functions are not available. I don't know if it is faster than Node after adding these functions.
  • The purpose of Bun is very strong. From the beginning, it knows what tools it needs to provide to solve what problems, so it will naturally design some optimized solutions according to specific scenarios, so in some scenarios, the performance will be advantageous, such as package management, etc.

Where does Bun get it right compared to Deno?

Compared with Deno, another previous Node replacement, I think Bun is doing two things right. One is to be compatible with the Node ecosystem instead of introducing new ones . This is actually very important, because Node has been used in many large companies since its release in 2009, and has a huge ecosystem. Deno didn't think about being compatible with Node at all from the beginning, so many of its wheels had to be rebuilt, and it was very difficult to migrate existing Node applications, so you can see that Deno v1 has been released for more than two years. Using Node. Fortunately, the Deno team is aware of these problems and allows you to use std/node to run some Node applications after 1.15. Unlike Deno, Bun put Node compatibility first at the very beginning. Although it has not yet achieved a fully compatible Node API, this is the goal it has been striving for. Think about it, if one day Bun becomes Node Seamless application migration, what about Deno?

Another thing that Bun does right is that it solves a pain point of the Node ecosystem, which is slowness , especially when installing dependencies and starting projects. These are important and common questions, so it can be a good reason for Node developers to be willing to migrate to full-blown Bun. On the contrary, Deno does not solve this problem, but solves some problems that I personally think are not so common, so the original Node developers are not motivated to migrate to Deno.

Can Bun replace Node?

Bun is so much better than Deno, so does it mean it can really replace Node? As a conclusion, I don't think Bun will replace Node, at least not in the next few years .

In my opinion, Bun has the following problems.

  • Limitations of Zig Language
  • All-in-one Architecture Design
  • far from complete functionality

Limitations of Zig Language

When talking about the reason why Bun is so fast above, it is mentioned that Zig language is a very young and unpopular language. Being very young means that the language may still have many bugs that have not been tested in practice. Not so popular means that the language developer group is small, which means that there are few potential developers of Bun's contributors. These reasons will hinder the development of Bun.

All-in-one Architecture Design

In my daily work, I found that if a person wants to do everything well, he often ends up doing nothing well. The reason is that a person's energy is limited.

While projects are different from people, analogies can also be drawn. Bun's goal is very lofty and wants to do everything, and wants to do everything well (if you don't do it well, others won't use it). There are two questions here, one is can you really do anything? According to the introduction of the official website, Bun now supports JSX, but the Transpile method of Vue and Angular is different from React. In addition to these two frameworks, there are other frameworks such as Svelte and there may be more new frameworks in the future. Can every framework support it? Another problem is that you want to do everything well, as I mentioned earlier when I mentioned the Zig language. This is a less popular language, which means that there are very few excellent programming experts in this area. Therefore, it is estimated that Bun will be developed later. It will be very difficult, can't rely on these people all the time? Since open source is out and community participation is king, and the limitation of Zig language means that there will be very few excellent developers that can participate, and the quality is naturally more difficult to guarantee.

On the contrary, I think Bun can learn the way of Unix having small independent tools that do one thing well and still can play together thinking. In other words, it is not necessary to do everything, but to provide a core similar to bun-core. This core is a JS runtime + package manager, which ensures Bun's fast JS running speed and efficient package. Management and compatibility with all NodeAPIs , because these are the core of it. Then bun-core provides APIs to support external expansion of its functions. This part of the extended functions is developed by the corresponding community developers, so that Bun will not eventually become a behemoth that can't do anything well.

far from complete functionality

The last reason I think Bun can't replace Node for the time being is that it still lacks many core functions, so it is far from being able to be used in a production environment. When introducing Bun's Transpiler function, you also found that Bun does not support common functions such as Minify and Tree-Shaking. In fact, it is more than that. If you look at Bun's RoadMap , you will find that it has 20% of the functions. It has not been developed yet, which means that it will take a long, long time before we can use it in practice.

Summarize

In this article, I introduced a brand new JS runtime Bun. Its biggest feature is that it is fast, but I think you can probably understand this technology and keep a certain level of attention now, so you don't have to rush into learning. Because its future path is still very uncertain, it cannot replace Node at present.

Personal technology trends

Pay attention to my official account - attack on the green onion to get my latest technology push

wechat.jpeg


进击的大葱
222 声望67 粉丝

Bitcoin is Noah's Ark.