How to set up a dev server with esbuild
Tags: esbuild, bundling, javascript
Published: 2021-08-10 17:31:29

In this article, I'll show how to add a development server to the simple application we started in [part 1](https://how-to.dev/how-to-start-building-a-project-with-esbuild).

# Possible approaches
There are two alternative ways we can achieve our goal. 

## Autorebuild
The first is to have the same setup we had in part 1, but watch files automatically rebuild them. This is provided by the `--watch` option - [the documation](https://esbuild.github.io/api/#watch). In our case, we can define a new npm script in `package.json`:
 
```JSON
{
  ...
  "scripts": {
    ...
  "scripts": {
    ...
    "watch": "esbuild --bundle src/index.js --outfile=www/main.js --watch"
    ...
```

With this in place, we can start the watch with:
```sh
$ npm run watch

> esbuild-tutorial@1.0.0 watch /home/marcin/workspace/github/esbuild-tutorial
> esbuild --bundle src/index.js --outfile=www/main.js --watch

[watch] build finished, watching for changes...
```

Then, after each change, the code is rebuilt:

```sh
[watch] build started (change: "src/index.js")
[watch] build finished
```

We access the page in the same as before - in my case, I have it at `http://localhost/github/esbuild-tutorial/www/`

## Development server

Another approach is to use the development server provided by esbuild. From the approaches presented in [the documentation](https://esbuild.github.io/api/#serve), the **server everything** one is simple to set up in our case.

When we add to `package.json`:
```json
{
  ...
  "scripts": {
    ...
  "scripts": {
    ...
    "start": "esbuild --bundle src/index.js --outfile=www/main.js --servedir=www",
    ...
```

We can start a dev server with:
```sh
npm run start

> esbuild-tutorial@1.0.0 start /home/marcin/workspace/github/esbuild-tutorial
> esbuild --bundle src/index.js --outfile=www/main.js --servedir=www


 > Local:   http://127.0.0.1:8000/
 > Network: http://192.168.2.107:8000/
 > Network: http://172.18.0.1:8000/
 > Network: http://172.17.0.1:8000/
```

Then, every reload of the page cause the build to be rerun:
```sh

127.0.0.1:44180 - "GET /" 200 [1ms]
127.0.0.1:44180 - "GET /main.js" 200 [0ms]
```

Not building ahead of time is a neat feature possible thanks to lighting fast builds in esbuild.

## Autorebuild vs. development server
If you have an HTTP server set up to point out to your work space, the auto rebuild can be a quick & dirty way to improve your workflow. Otherwise, the dev server is the way to go.

# Don't repeat yourself

With our current scripts, we have:
```JSON
{
  ...
  "scripts": {
    ...
    "build": "esbuild --bundle src/index.js --outfile=www/main.js",
    "start": "esbuild --bundle src/index.js --outfile=www/main.js --servedir=www",
    "watch": "esbuild --bundle src/index.js --outfile=www/main.js --watch"
...
```

The part repeated in all 3 places - `esbuild --bundle src/index.js --outfile=www/main.js` will easily become a headache when needed to be changed. We can reuse the shortest command and add the additional flag to it in the others:
```JSON
{
  ...
  "scripts": {
    ...
    "build": "esbuild --bundle src/index.js --outfile=www/main.js",
    "start": "npm run build -- --servedir=www",
    "watch": "npm run build -- --watch"
  },
...
```

# Links

The code is in in example [repository](https://github.com/marcin-wosinek/esbuild-tutorial), in the [step-2 branch](https://github.com/marcin-wosinek/esbuild-tutorial/tree/step-2).

You can check out my [video course about esbuild](https://bit.ly/esbuild-course).

# Summary

In this article, we have seen how to set up a dev server. In the next article, we will make our application a bit more complicated & we will add styling. If you want to be updated when the next article is published, you can [sign up here](https://landing.mailerlite.com/webforms/landing/b8k4x6)/b8k4x6).