Bun Now Supports Cross-Compiling Executable Binaries

| 7 min read
Author: masahiro-kondo masahiro-kondoの画像
Caution

This article has been automatically translated.
The original article is here.

Introduction

#

When Bun reached version 1.0 last September, I wrote an article about introducing it into the development environment.

Replacing Node.js with Bun in the Development Environment

Later, with Bun 1.1, Windows support was added, achieving true cross-platform compatibility.

Bun 1.1 | Bun Blog

While the feature to generate executable binaries was already provided, the cross-compiling feature was implemented in version 1.1.5.

Bun v1.1.5 | Bun Blog

Promotion - Contributed to the Bun Feature in Software Design June 2024 Issue

Inspired by the article introduced at the beginning, I had the opportunity to contribute to the second feature on Bun in the June 2024 issue of Software Design. It covers everything from an overview of Bun to how to use it and performance comparisons with Node.js.

  • Chapter 1: Grasping the Big Picture of Bun
  • Chapter 2: Let's Use Bun
  • Chapter 3: Thorough Comparison of Bun and Node.js

I was responsible for writing Chapter 2. I wrote about installing Bun, introducing its features, how to use it, and debugging methods. At the time of writing, it was just after the release of Bun 1.1, so I didn't touch on cross-compiling. However, I did introduce how to create executable binaries.
Chapter 3 includes interesting content such as deploying Node.js and Bun code to AWS Lambda for speed comparisons.

SD202406

Software Design June 2024 Issue

Advantages of Single Binary and Cross-Compiling

#

The benefits of creating a single binary include not only the convenience of distribution to users but also the following advantages:

  • Saves time and memory as there is no need for import resolution, transpiling, or code generation at runtime.
  • Enables lightweight containers as binaries can be containerized without a runtime by simply copying the binary.
  • Simplifies the CI pipeline as the binary can be executed by just downloading and setting the path, saving execution time.

Additionally, cross-compiling offers the following advantages:

  • No need to prepare a build environment for each target environment.
  • Can build executable binaries for all targets with a single CI pipeline.

Therefore, with the implementation of the cross-compiling feature in Bun, which originally boasts an all-in-one approach, the development experience has significantly improved as the bun CLI alone can handle everything from development to cross-platform executable binary distribution.

Trying Bun's Cross-Compiling

#

Let's try generating and cross-compiling an executable binary with Bun. I am performing this on a macOS Sonoma / Bun 1.1.8 environment.

Create a Bun project.

mkdir simple-server && cd simple-server
bun init -y

I wrote a simple HTTP server that listens on port 3000 and returns a message.

index.ts
Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response('Hello, Bun!')
  }
});

This code can be executed with the following command.

bun index.ts

Let's create an executable binary.

$ bun build --compile ./index.ts --outfile simpleServer
   [2ms]  bundle  1 modules
 [104ms] compile  simpleServer

The build completes in about 0.1 seconds, generating a 51MB executable binary targeting the macOS machine.

$ ls -lh simpleServer
-rwxrwxrwx  1 kondoh  staff    51M  5 20 14:50 simpleServer

It can be executed without the bun CLI as follows.

./simpleServer

In the above example, the target was not specified, but the platform can be specified with the --target option. Let's generate a binary for Windows.

$ bun build --compile ./index.ts --target=bun-windows-x64 --outfile simpleServer.exe
   [3ms]  bundle  1 modules
[4.302s] compile  simpleServer.exe bun-windows-x64-v1.1.8

Including the download of necessary libraries, the build completes in about 4.3 seconds. The file size is around 100MB.

$ ls -lh simpleServer.exe
-rwxrwxrwx  1 kondoh  staff   105M  5 20 14:55 simpleServer.exe

The --target specification is as follows.

Platform --target Value
Linux x64 bun-linux-x64
Linux ARM bun-linux-arm64
Windows x64 bun-windows-x64
macOS x64 bun-darwin-x64
macOS Apple Silicon bun-darwin-arm64

When deploying to production, it is also recommended to specify --minify and --sourcemap.

bun build --compile --minify --sourcemap ./path/to/my/app.ts --outfile myapp

Specifying the --minify option can reduce the size of the transpiled code. Specifying the --sourcemap option allows error information to be output at the location of the original source code.

Additionally, embedding assets and embedding SQLite databases are also supported. For more details, refer to the documentation.

Single-file executable – Runtime | Bun Docs

Implementation Status in Major Runtimes

#

Executable binary generation is also implemented in Node.js and Deno, and cross-compiling is already implemented in Deno.

Deno Bun Node.js
Executable Binary Generation ⚪︎ ⚪︎ ⚪︎ (Active development)
Cross-Compiling ⚪︎ ⚪︎ -

Regarding Node.js Single Executable Applications, it is currently in the stability: 1.1 - Active development status and cannot be considered stable at this point. The situation is that the newer runtimes Deno and Bun are on par.

Information

Although it's an article from last year, our site has covered Node.js Single Executable Applications in the following article.

Creating Standalone Executable Files with Node.js v19.7 Experimental Single Executable Applications

Conclusion

#

We have tried cross-compiling executable binaries implemented in Bun.
The ability to reduce the footprint and speed up the startup in the deployment environment with executable binaries is a significant advantage.
Ultimately, it is necessary to conduct end-to-end tests for each target platform in CI, but it is nice that the development environment only needs to be for one platform thanks to the cross-compiling feature.

豆蔵では共に高め合う仲間を募集しています!

recruit

具体的な採用情報はこちらからご覧いただけます。