A Comprehensive Guide to Building Node APIs with esbuild
Tags: javascript, node, programming, tutorial
Published: 2022-04-24 20:24:50

One of the most interesting things about building an api in Node is the fact that we can choose the tooling we want to use or experiment with. And one of the things we can choose is our compiler, in the case of this article we will be interested in transpiling transpiling the code from TypeScript to JavaScript in a quick way during the development process. Just like we want to have that quick build to use in our production environment.

To be honest, I'm a big fan of SWC, but I had no idea that there were dependencies that help us configure a project with esbuild in a super fast and simple way. It's so easy but so easy, to the point that we can make the migration from babel to esbuild in the blink of an eye.

## Project Setup

First let's start with the usual one, which is to create the project folder:

```sh
mkdir ts-esbuild
cd ts-esbuild
```

Next, initialize a TypeScript project and add the necessary dependencies:

```sh
npm init -y
npm install -D typescript @types/node
```

Next, create a `tsconfig.json` file and add the following configuration to it:

```js
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "allowJs": true,
    "removeComments": true,
    "resolveJsonModule": true,
    "typeRoots": [
      "./node_modules/@types"
    ],
    "sourceMap": true,
    "outDir": "dist",
    "strict": true,
    "lib": [
      "esnext"
    ],
    "baseUrl": ".",
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "moduleResolution": "Node",
    "skipLibCheck": true,
  },
  "include": [
    "src/**/*"
  ],
  "exclude": ["node_modules"],
}
```

Now with our TypeScript environment configured, we can now install the dependencies we need to use the esbuild, for the build and development process (with live reloading).

```sh
npm install -D nodemon esbuild esbuild-node-tsc
```

With these dependencies installed we can configure `nodemon.json`:

```js
{
  "watch": ["src"],
  "ignore": ["src/**/*.test.ts", "node_modules"],
  "ext": "ts,mjs,js,json,graphql",
  "exec": "etsc && node ./dist/server.js",
  "legacyWatch": true
}
```

Now in our `package.json` we are going to specify that we are going to use ESM and we are going to add the following scripts:

```js
{
  // ...
  "main": "server.js",
  "scripts": {
    "dev": "nodemon",
    "build": "etsc",
    "start": "node dist/server.js"
  },
  // ...
}
```

Whenever nodemon sees a change in our source code, as soon as there is one, it builds the folder and then reloads the api. However, the code being executed is not TypeScript but the JavaScript code that will be saved in the `dist` folder.

Finally, we can create a simple api:

```js
// @/src/server.ts
import fastify, {
  FastifyRequest,
  FastifyReply,
  FastifyInstance,
} from "fastify";

const startServer = async (): Promise<FastifyInstance> => {
  const app = fastify();

  app.get("/", async (request: FastifyRequest, reply: FastifyReply): Promise<FastifyReply> => {
    return reply.send({ hello: "world" });
  });

  return app;
};

startServer()
  .then((app) => app.listen(3333))
  .catch(console.error);
```

Creating an api in Node using TypeScript along with the esbuild is as simple as this, literally. One thing I want to mention, but I think you've noticed this, `esbuild-node-tsc` takes into account the `tsconfig.json` configuration but the build is done with esbuild.

If you want to try it out without having to configure all this (although it wasn't much), you can clone [this](https://github.com/FranciscoMendes10866/esbuild-config) repository. Have a nice day 👊