In this post I will extend the setup adding TailwindCSS for styling, Jest for unit testing.
Configuring TailwindCSS
To enable TailwindCSS we need to add PostCSS and write a small esbuild plugin to enable TailwindCSS in our css file.
First we'll need to install the following dependencies:
npm i --save-dev postcss tailwindcss @tailwindcss/postcss
Now lets create a esbuild plugin that we can add to our scripts to enable postcss and tailwindcss:
import{readFile}from'node:fs/promises';importpostcssfrom'postcss';// esbuild Plugin to process css files with postcssexportconstpostcssPlugin=({plugins=[]}={})=>{return{name:'postcss',setup(build){build.onLoad({filter:/\.css$/},async (args)=>{constraw=awaitreadFile(args.path,'utf8');constsource=awaitpostcss(plugins).process(raw.toString(),{from:args.path});return{contents:source.css,loader:'css'};});}};}exportdefaultpostcssPlugin;
In your esbuild configuration now we can use the plugin:
Since version 4 tailwindcss does not require a config script but instead configures it with CSS. This is a basic style.css using dynamic background and foreground colors:
To enable Jest in our project we will use @testing-library as it will facilitate the configuration and testing utilities.
Install the following dependencies:
npm i --save-dev jest jest-environment-jsdom @testing-library/jest-dom @testing-library/react @types/jest
To configure Jest with react and esbuild we'll need to create a transformer to transpile typescript and jsx.
import{transformSync}from'esbuild';exportdefault{process(src,filename){// Ensure only TypeScript and JavaScript files are processedif (/\.(ts|tsx|js|jsx)$/.test(filename)){constresult=transformSync(src,{loader:filename.endsWith('ts')||filename.endsWith('tsx')?'tsx':'jsx',format:'esm',// ESM formatsourcemap:'inline',// Inline sourcemaps for debuggingtarget:'esnext',// Set the target to latest ECMAScripttsconfigRaw:{compilerOptions:{jsx:'react-jsx'},}});return{code:result.code,map:result.map};}returnsrc;},};
We'll also need a environment setup file to import jest-dom from @testing-library that way we can use the library matches like toBeInTheDocument and toBeInTheDOM.
import'@testing-library/jest-dom';
Lastly we can create a config file jest.config.json that will use our custom esbuild transformer and setup file.
This will allow us to run jest test files in the project. since we are using esm we have to use node --experimental-vm-modules flag.
There are also others utilities that are commonly used in react projects like importing SVG as Components and auto reload on changes. I have included these in my repository:
A Simple react app setup with SSR, CSR, Jest, TailwindCSS and esbuild
A Simple react app setup with SSR and esbuild
This project leverages the latest features of react@19, react-router-dom@7, and others to configure SSR.
Depdendencies
react: Component-based and interactive UI library.
react-dom: Hydrates SSR content with React functionality.
react-router-dom: Handle Routes with React.
express: Node.js simple server for static and REST APIs.
esbuild: Transile TypeScript and bundle JS, CSS, SVG, and other files.
typescript: Adding Typing to our source code.
jest: Unit testing.
postcss: Preprocess css files.
tailwindcss: css utilities.
svgo: converting svg to JSX component modules.
Project Structure
react-app/ # This will be our workspace directory.
- public/
- scripts/
- build.js # Bundle our server and client scripts.
- config.js # esbuild config to bundle.
- dev.js # Bundle on watch mode and run server.
- src/
- App/ # Our components will be here.
- App.tsx # The