DEV Community

Cover image for How to Build a Node API with esbuild
Francisco Mendes
Francisco Mendes

Posted on

How to Build a Node API with esbuild

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:

mkdir ts-esbuild
cd ts-esbuild
Enter fullscreen mode Exit fullscreen mode

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

npm init -y
npm install -D typescript @types/node
Enter fullscreen mode Exit fullscreen mode

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

{
  "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"],
}
Enter fullscreen mode Exit fullscreen mode

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).

npm install -D nodemon esbuild esbuild-node-tsc
Enter fullscreen mode Exit fullscreen mode

With these dependencies installed we can configure nodemon.json:

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

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:

{
  // ...
  "main": "server.js",
  "scripts": {
    "dev": "nodemon",
    "build": "etsc",
    "start": "node dist/server.js"
  },
  // ...
}
Enter fullscreen mode Exit fullscreen mode

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:

// @/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);
Enter fullscreen mode Exit fullscreen mode

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 repository. Have a nice day 👊

Discussion (0)