SECRET OF CSS

3 Ways To Use Bun With Create React App | by Jennifer Fu | Aug, 2022


Exploring bun.js using Create React App (CRA)

Image by author — The logo is from https://bun.sh/

A bun is an unsweet bread roll typically filled with savory fillings, such as hamburger. Baozi, or bao, is a yeast-leavened-filled bun in various Chinese cuisines. There are many variations in fillings (meat or vegetarian) and preparations, though the buns are most often steamed. Bao typically looks like the above image, and Bao is also a short film made By Disney Pixar.

In this article, we talk about a different bun, which is a fast all-in-one JavaScript runtime. Bun is a modern JavaScript runtime like Node or Deno, with a native bundler, transpiler, task runner, and npm client built-in — all in Bun.

Bun.js was created on April 2021, and it is fairly young. The latest Bun version is 0.1.7, which was released on August 6, 2022. It is not production-ready yet.

Bun is fast, and its performance comes from the following technologies:

  • JavaScriptCore: It is a built-in JavaScript engine for WebKit, which is faster than V8.
  • Zig: It is a general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
  • esbuild: It is an extremely fast JavaScript/CSS bundler and minifier.

Bun internally uses ESM, although it also supports CommonJS. It has built-in Web APIs, such as fetch, WebSocket, and ReadableStream. In Bun, every file is transpiled. Therefore, TypeScript and JSX just work. It is a great and complete tool as a bundler, transpiler, and package manager.

Run the command, curl https://bun.sh/install | bash, to install Bun:

  1. As it shows in line 7, the Bun path has been added to .zshrc.

2. As it shows in line 9, run exec /bin/zsh to update the path in the current shell. Now the Bun command is recognized:

Here is the help manual:

Create a TypeScript of Hello World:

We can execute the TypeScript out of the box — without setting it up. tsconfig.json.

Since Bun is proud of its speed, it always displays the time to execute the command.

With Bun installed, we have three ways to use it with Create React App (CRA):

  • Use a Bun-enabled CRA
  • Use Bun to execute CRA
  • Convert regular CRA to a Bun project

bun create is a fast way to create a new project from a template. Bun has a template to set up a CRA project. The command is bun create react <myDirectory>.

By default, bun run prints the scripts that will be invoked, which can be disabled with the —-silent flag. The console output shows that it ran two scripts:

  1. bun install (line 4): It installs dependencies in package.json. Eight packages are installed.
  2. bun bun ./src/index.jsx (line 19): It bundles dependencies recursively from ./src/index.jsx to all imported dependencies into a binary .bun file, named node_modules.bun. The .bun file contains all the bundled source code, all the bundled source code metadata, project metadata, and configuration. The content can be printed out by the command, bun node_modules.bun.

At line 49, it shows that it took 1,182 ms to create the project. It is much faster than regular CRA.

At lines 61–62, it shows the commands to go to the project directory, bun-enabled-react, and to execute the app by running bun dev.

Here is package.json in the created project:

It looks a lot simpler than the regular CRA’s package.json listed below:

Bun’s package.json lacks the functionality to make a production build and to execute unit tests.

Bun’s lock file is bun.lockb, instead of package-lock.json. It is a binary lock file, and bun install -y prints a Yarn v1-style yarn.lock file.

The lock file stores a lot more data than a regular lock file. It stores packages, metadata for those packages, the hoisted install order, dependencies for each package, what packages those dependencies resolved to, an integrity hash (if available), what each package was resolved to, and which version (or equivalent).

bun.lockb is fast because it uses linear arrays for all data. Packages are referenced by an auto-incrementing integer ID or a hash of the package name. Strings longer than eight characters are de-duplicated. Before saving on disk, the lock file is garbage-collected and made deterministic by walking the package tree and cloning the packages in dependency order.

Bun is zero configuration. If needed, bunfig.toml can be used for configuring bun install, bun remove, and bun add.

By default, local files are located at ~/.bun, where executables are stored in ~/.bun/bin and packages are cached in ~/.bun/install/cache.

Execute bun dev in the bun-enabled-react directory:

On a browser, we see the Bun-enabled CRA running, similar to the regular CRA. It shows the text, <h3>Welcome to React!</h3>.

The bun enabled CRA, with the text, “Welcome to React!”
Image by author

There is an error on the console, which is a known issue.

404 GET /manifest.json as application/octet-stream

We create a regular React project using npx:

% npx create-react-app regular-react
% cd regular-react

During the installation, it prints out the following npm commands available to run:

We can use yarn to execute these commands, as well as Bun.

Execute bun start in the regular-react directory. On a browser, we see the regular CRA, executed by Bun. It shows the text, <p>Edit <code>src/App.js</code> and save to reload.</p>.

The regular CRA, with the text, “Edit src/App.js and save to reload.”
Image by author

We have a Bun-enabled CRA (left in the picture below) and a regular CRA (right in the picture below).

The comparison of a bun enabled CRA and a regular CRA
Image by author

Reading line by line, we can tell that the two projects are extremely similar, except for the following differences:

  • The file on the left side is called App.jsx, and the file on the right side is called App.js.
  • There is an extra TypeScript definition, images.d.ts on the left side.
  • There is an extra test file, App.test.js on the right side.
  • The file on the left side is called index.jsx, and the file on the right side is called index.jsx.
  • There is an extra setup file, setupTests.js on the right side.
  • The file on the left side is called bun.lockb, and the file on the right side is called package-lock.json.
  • There is an extra setup file, node_modules.bun on the left side.

Let’s see what needs to be done to convert regular CRA to a Bun project.

Execute bun dev in the regular-react directory. On a browser, we see a blank screen:

The CRA, with the blank screen
Image by author

What went wrong?

After comparing each files, we found out the fix is adding line 42 in public/index.html.

It needs to embed <script type="module"> to apply the /src/index.js module to the HTML page. async is not necessary, but it allows the script to be downloaded in parallel to parsing the page and executed as soon as it is available.

One line code change is all we need to convert regular CRA to a Bun project.

Execute bun dev in the regular-react directory. On a browser, we see the CRA running.

The regular CRA, with the text, “Edit src/App.js and save to reload.”
Image by author

Bun is a fast all-in-one JavaScript runtime. It is a modern JavaScript runtime like Node or Deno, with a native bundler, transpiler, task runner, and npm client built-in — all in Bun.

We have explored three ways to use Bun with CRA. For daily coding life, the Bun executable works in situations where npm or yarn works. Bun is young and promising, and we are looking forward to its production release.

Thanks for reading.

If you are interested, check out my directory of web development articles.



News Credit

%d bloggers like this: