DEV Community

Mrinalini Sugosh (Mrina)
Mrinalini Sugosh (Mrina)

Posted on • Updated on

React+Typescript App with ESBuild

There is a project called ESBuild, basically a bundler like web-pack or rollup, and it has been making a lot of noise in the Front-End Development space. Why? Primarily because of its promise to deliver extremely high performance.

image

Source - https://esbuild.github.io/

I would say this is especially great for large projects or large teams. In fact, it even supports Typescript out of the box which is why I am interested in it. In this blog, we will explore ESBuild and use it to build a simple Typescript+React app.

Let's get started!

Setup the Project

First, let's create a new directory and initialize a new package.json file:

mkdir sample-ts-react-app
cd sample-ts-react-app/
npm init -y
Enter fullscreen mode Exit fullscreen mode

image

Then the only thing we need to install to set up our bundler is esbuild:

npm i esbuild
Enter fullscreen mode Exit fullscreen mode

image

Since we are building a react app we are going to install React and ReactDom along with the type definitions for these two packages and the typescript compiler as folllows:

npm i react react-dom @types/react @types/react-dom typescript
Enter fullscreen mode Exit fullscreen mode

image

Once the installation is complete, let's use the Typescript Compiler to initialize a new tsconfig.json. Here we will also specify that all of our source files will be under the src/ folder and that we will be using react:

npx tsc --init --rootDir src --jsx react
Enter fullscreen mode Exit fullscreen mode

image

That's it! We have setup our project, now let's open up the the folder in an IDE, I am using Visual Studio, but you can use one of your choice.

Write up the sample app

Let's create application entry point under thesrc folder as app.tsx:
image

Now let's write some basic code. Here we import some of the common libraries and hooks including: React, useCallback, useState, and ReactDOM. Our app will consist of a simple component that will take a message as a prop, have an internal state for a counter that is initialized to 0, a callback function that increments the count by 1, and simple UI that shows this information.

import React, { useCallback, useState } from "react";
import ReactDOM from "react-dom";

const App = (props: { message: string }) => {
    const [count, setCount] = useState(0);
    const increment = useCallback(() => {
        setCount(count => count + 1);
    }, [count]);
    return(<>
        <h1>{props.message}</h1>
        <h2>Count: {count}</h2>
        <button onClick={increment}>Increment</button>
    </>)
};
Enter fullscreen mode Exit fullscreen mode

Then let's render out this app component with a simple message using the ReactDOM onto the root element within our html.

ReactDOM.render(
  <App message="Hello World! Simple Counter App built on ESBuild + React + Typescript"/>,
  document.getElementById('root')  
);
Enter fullscreen mode Exit fullscreen mode

Of course the next step is to actually create this HTML that our app will sit on. We will do this by creating a sibling folder to src called public/index.html. This file will contain a simple div with an id root which we will render the previous React App component to and a script to load the JS Bundler.

That's it for our app!

Bundle App with ESBuild

Next step is to use ESBuild to bundle our app.tsx. If you have worked with webpack or rollup, you know this process.

Before we bundle, I will first add a script in the package.json called build which will invoke ESBuild and pass in the entry point for the app along with a few flags (bundle, minify, and sourcemap) and an output target public/bundle.js.

//pacakage.json
"scripts": {
   "build": "esbuild src/app.tsx --bundle --minify --sourcemap --outfile=public/bundle.js"
}
Enter fullscreen mode Exit fullscreen mode

Oila and just like that when you run npm run build we should be able to complete building our app almost in a blink of an eye (30ms!!!)
image

Finally running the app should be simple enough. Just point to the index.html file and it should run:

open index.html
Enter fullscreen mode Exit fullscreen mode

How does ES Build achieve such speeds?

ESBuild compiler actually targets the Javascript Ecosystem but it is written in Go. Now I am personally a fan of bootstrap projects, for example, the typescript compiler being written in typescript. However, this level of performance improvement a Go compiler for Javascript project does make it worthwhile for me.

You might have also noticed that ESBuild is also much more lower level when compared to something like webpack. If you want the same level of developer ergonomics as webpack, like webpack dev-server, you might have to combine ESBuild with something like Vite or Snowpack. In fact, these tools actually use ESBuild under the hood!

All in all, ESBuild is still a great starting point to test how fast you can potentially build your application. Of course, you are free to explore using this skeleton code and build on it. I am personally looking forward to hearing your thoughts and experiences on ESBuild!

Discussion (8)

Collapse
ted_lee_2697 profile image
Ted Lee • Edited on

Great blog and thoughts! Can you make another post on Snowpack or Vite? Been thinking of migrating our project to snowpack but wanted some benchmarking and resources beforehand.

Collapse
hedwardd profile image
Heath Daniel

I was thinking the same thing! After reading this, I now want to know more about Snowpack and Vite (mostly around how to get development mode running with this setup).

If you had an article I'd definitely read it πŸ˜„

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

Great idea! Let me think through it and probably will post about it in the future? Are y’all looking for some benchmarking or another walkthrough to setup a project with Vite or Snowpack?

Thread Thread
hedwardd profile image
Heath Daniel

Well, since I spend most of my time in developer mode, I'm wondering if a) the benchmark differences carry over there and b) how complicated it is to get set up.

At the very least, I'd be curious to know if the benchmarks carry over (along with where I might go learn how to set it up) because that could convince me to try it. Either way, this one was a great article!

Collapse
lukeshiru profile image
LUKESHIRU • Edited on

One other thing that adds to the speed factor of esbuild is that it doesn't actually compiles TS, it only removes the types like babel does. If you're planning on making a library that includes types to be used by your consummers, you need to consider that you still need to generate the types using tsc.

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

Yess +1! Great point and absolutely recommend folks to look into the nits of ESBuild some great yet simple tech backing it up

Collapse
loopmode profile image
Jovica Aleksic

I recently switched a create-react-app setup of an existing medium-size app to esbuild, using craco and craco-esbuild, and I was disappointed. Any perf gains were miniscule, like 40s instead of 50s build time and barely if any noticable improvements in other areas (dev startup, recompile).

However, I didn't inspect what actually got changed, e.g. it's probably still a largish webpack setup just swapping babel for esbuild.

I have to try a fresh setup like you did in this article. Thanks for the good article!

Collapse
mrinasugosh profile image
Mrinalini Sugosh (Mrina) Author

Awesome! I am soo glad you found it useful. Do share your experience would be interested to know how it plays out for you