Using Bun.js as a bundler

Mai 17, às 21:46


7 min de leitura


0 leituras

Bun.js is a new (as of 2023) JavaScript runtime that is still very much in development, with it's primary focus being on extreme speed. I've been following it for a while but until today haven't had a good excuse to use it. The author, Jarred Sumner, announced on Twitter today that they have shipped a…
Using Bun.js as a bundler

Bun.js is a new (as of 2023) JavaScript runtime that is still very much in development, with it’s primary focus being on extreme speed. I’ve been following it for a while but until today haven’t had a good excuse to use it.

The author, Jarred Sumner, announced on Twitter today that they have shipped a beta version of a new code bundler for Bun, showing some crazy speed increases over other bundlers. This piqued my interest, as I use a combination of Webpack, Browserify and Uglify on my side projects, in this case my tablet PWA that I built for my kids, which work but are really slow.

My current workflow can result in a 5 – 7 second wait for all my JS files to rebuild when I save a file, and I thought that Bun could help with this. It turns out I was right! …. with caveats.

You can see the docs for at , and they are well written and quite comprehensive.

My requirements were to

  • Build multiple files quickly, each of which imports multiple other 3rd party files from node_modules.
  • Build minified and non-minified files
  • The resulting file can be included directly in a browser using a <script> tag.

Getting started

I started off by running default build code (for Bun v0.6.1)

const myFiles = [...];
 entrypoints: [myFiles],
 outdir: './build'

by adding a script to my package.json file

 "build-browser": "bun scripts/build-browser.js"

and this worked just fine. More importantly, it was crazily fast. Instead of 5 seconds it now seemed to finish as the Enter key was still traveling back upwards from executing the command. Nice!


Minification looks simple in the docs, but unfortunately it’s where the beta nature of Bun shows up. Running the code above with minification

const myFiles = [...];
 entrypoints: [myFiles],
 outdir: './build',
 minify: true

results in an error being thrown that shuts down the process if there is more than one entry point file.

Searching the web didn’t turn up anything, but the solution is to only pass a single entry point file path to if you are minifying the code. Throw that in a for loop to get through all the files and it runs just fine!

A second issue with the default minification is that it broke my app in strange ways that I could not track down – I’m guessing that it’s rewriting the code in some way that is not fully stable yet. I solved it by turning off the syntax minification option

const myFiles = [...];
 entrypoints: [myFiles],
 outdir: './build',
 whitespace: true,
 identifiers: true,
 syntax: false // Setting this to false fixes the issue

Removing Exports

Bun inserts code that looks like this at the bottom of the built file, in this case from a file called account.ts

var account_default = {};
export {
 account_default as default

If you load this in a browser <script> tag it will throw an error. I couldn’t find a way to tell Bun how to not output this, so I had to write a relatively simple function to detect this at the end of each output file and remove it.

Watch issues

I have some code that uses the node-watch module to automatically re-run the build when a file changes. Under the hood this uses the function, which it turns out Bun does not yet support. Here’s the Github issue tracking it. I tried to use the native Bun watch functionality, but this executed the script code which is not what I’m looking for.

I came up with a hacky solution that works fairly well, where I use the RunOnSave extension for VS Code to execute

touch ./.last_modified_timestamp

every time I save a file. Then in my build script I use setInterval to check the last modified time of this file and re-run the build if it has changed. Hacky but it works. Hopefully Bun will implement soon and I can throw out this code.

function build() {
const timestampFilePath = `${rootDir}/.last_modified_timestamp`;
if (fs.existsSync(timestampFilePath)) {
 let lastModifiedRootFolder = 0;
 setInterval(() => {
 const stat = fs.statSync(timestampFilePath);
 if (stat.mtime.getTime() !== lastModifiedRootFolder) {
 lastModifiedRootFolder = stat.mtime.getTime();
 }, 500);

Vercel build failures

Once everything was running just fine locally on my Mac, I pushed the branch to Github so Vercel would build it (it’s a NextJS application). This threw up a new issue. My build script uses the native Node exec() function to move and copy files. This works just fine on my Mac, but when running the build in the cloud environment all these calls would fail. There’s something unfinished with Bun’s implementation of the child_process module that breaks when run in the Vercel build environment.

My solution to this was to simply change all these execSync calls to use the Node fs functions, e.g.

import fs from 'fs';
fs.copyFileSync(srcPath, destPath);
fs.renameSync(path, `${rootDir}/public/${fileName}`);


After a few hours of work, reading up on Bun and working my way through these issues, I now have a much simpler build system that runs in the blink of an eye. My Vercel build times have reduced from 2 minutes to just 50 seconds (that’s all React stuff & fetching node_modules). My watch script runs in a few milliseconds instead of 5 or more seconds, My code is much simpler and I’ve removed Webpack, Browserify and Uglify from my projects.

Thanks so much to the Bun team for a great project. Even as early as it is at time of writing (mid 2023), it’s highly useful, and as they work through all the kinks it will only get more so. I look forward to using it more in the months and years to come!

Published by Shane O'Sullivan

I am a software engineer and manager from Ireland. I spent 7 years working in Ireland from 2003 – 2010, then ten years in Silicon Valley from 2010 to 2020. In California I spent about 6.5 years at Facebook Engineering, the last three of which I was an engineering manager in the Ads organisation focusing on customer facing products for creating and managing ads. At Stripe I built the Developer Productivity organisation, with teams that were responsible for the use of the Ruby language, testing infrastructure, documentation, developer tooling (e.g. IDE integrations) and more. At Promise, I was Head of Engineering from 2018 – 2020, responsible for building the first few iterations of our products, hiring for all product roles, meeting with clients and investors, and anything else needed to get a tiny startup bootstrapped and successful. Now I’m back in Ireland, working on my next company. Coming soon (as of early 2021!). This blog contains my various musings on all things technical/interesting on the interweb and beyond. View all posts by Shane O'Sullivan

Published May 17, 2023May 17, 2023

Continue lendo


Founding Developer of WordPress: I Just Paid for Twitter Blue - Here's Why | HackerNoon
Start WritingNotificationssee moreFounding Developer of WordPress: I Just Paid for Twitter Blue - Here's Why [email protected] 26th 2023 New Story by @techtweeter Too Long; Didn't Read3. I believe in...

Mai 26, às 21:45


Google lança API para exibir extensões na barra lateral do Chrome
O Google está lançando uma nova API chamada Chrome Side Panel, que permite que extensões do Chrome exibam interfaces na barra lateral do navegador. A novidade possibilita que as extensões criem “experiências...

Mai 26, às 21:24

IT Forum

OLX Brasil anuncia novo CEO: Olivier Aizac - IT Forum
Olivier Aizac (esquerda) e Andries Oudshoorn. Foto: Kaique Talles, Divulgação A OLX Brasil anunciou nessa sexta (26) a nomeação do executivo francês Olivier Aizac como Chief Executive Officer (CEO). A...

Mai 26, às 20:20


Concordex Launches Testnet Of Its Concordium-Built Institutional Focused DEX | HackerNoon
Too Long; Didn't ReadConcordex, the first dedicated decentralized exchange (DEX) built on the Concordium blockchain, has officially launched its testnet. The project raised $1.7 million in seed funding from...

Mai 26, às 20:09


Lançamentos do Amazon Prime Gaming em junho de 2023: SteamWorld Dig 2 e mais!
Índice Todos os lançamentos do Amazon Prime Gaming em junho de 2023Jogos gratuitos do Prime Gaming de junho de 2023Mutation NationSengoku 2Over TopSoccer BrawlSteamWorld Dig 2The Super SpyTop...

Mai 26, às 18:34


Implante cerebral da Neuralink já pode ser testado em humanos
Índice O histórico da tentativa da empresa de Musk de testar implante cerebralComo a Neuralink pesquisa a interação entre cérebro e máquina?O que as pesquisas em cérebros humanos na Europa conseguiram?Como...

Mai 26, às 18:33


THE SIX | HackerNoon
Too Long; Didn't ReadONE evening, at twilight, they were assembled in a group, all six of them. Uncle Paul was reading in a large book. He always reads to rest himself from his labors, finding that after work...

Mai 26, às 18:23


The Story-book of Science by Jean-Henri Fabre - Table of Links | HackerNoon
The Story-book of Science by Jean-Henri Fabre - Table of Links [email protected] Long; Didn't ReadThe Story-book of Science by Jean-Henri Fabre is part of the HackerNoon Books Series. Read this book...

Mai 26, às 18:22

IT Forum

Apple, Tesla e Amazon lideram ranking do BCG das mais inovadoras do mundo - IT Forum
Imagem: Shutterstock As empresas de tecnologia mantêm a liderança no ranking das 50 empresas mais inovadoras do mundo realizado pelo Boston Consulting Group (BCG). A Apple ocupa o primeiro lugar da lista...

Mai 26, às 18:15


Kingston lança pendrive com senha para maior segurança
Índice Linha IronKey para dados sensíveis Pendrive Locker +50 Vault Privacy 50 Ironkey Privacy 200Kingston ajuda usuários em nova compra A Kingston Brasil convidou jornalistas e influencers a comparecem ao...

Mai 26, às 16:56