How to use ESBuild to create a clean, fast building project
Whenever I work on an existing project or start a new one, I try to keep the dependencies minimal. My goal with dependencies is to make sure they are supported, stable, and robust.
Trying to keep dependencies minimal on NodeJS project is a challenge. Javascript makes it really easy to create modules, and NPM makes publishing your modules super easy. Some developers take this ease of use, and availability in the wrong direction. They install dependencies for every little functionality that their project needs. Even some things that come standard with Javascript.
One major utility that most projects use is a bundler/builder. There are many different bunders within the NodeJS ecosystem. Some popular options for this utility include, Webpack, Parcel, Vite, and Rollup.
Today I wanted to write about one such bundler that I think has a lot of potential, ESBuild. It bills itself as an "extremely fast bundler" which it is, but it also provides most of it's functionality in the CLI. The CLI for ESBuild allows for a clean setup that does not require configuration files that crowd your projects.
I use this bundler to create a simple project structure like the one below
.
├── scripts
│ ├── build.sh
│ ├── dev.sh
│ ├── deploy.sh
├── src
└── tests
The scripts folder contains all the build scripts that are necessary for the project. Anything that would be done using the bundler config, for example, copying static files, will be done using the build scripts. As well as using the CLI for ESBuild to bundle everything together. Here is an example of a build script that I use.
#! /bin/bash
set -e
rm -rf build
# Lambdas
npx esbuild ./src/index.js \
--bundle \
--minify \
--format=esm \
--platform=node \
--target=node22 \
--outfile=build/out.mjs
# Static fils
cp ./src/example.json ./build/
It's a simple bash script that first uses set -e
to set the flag to exit immediately if any of the commands in the script exit with a non-zero exit code. Then removes the build directory if one exists. Then runs the esbuild
CLI with various CLI options to build the bundle. And finally copy a static into the build directory to be used in the code. All of the is achieved without plugins or any extra node modules.
Although I didn't use plugins for ESBuild. It does support plugins. But you have to use the config file to be able to use them. That is a limitation of the CLI that it doesn't allow you use to any plugins for ESBuild. But with the power that shell scripts already have using the plethora of tools available for it, I don't think the plugins are necessary most of the time.
Happy hacking 🙂