DEV Community

Will Medina
Will Medina

Posted on • Edited on

Complete React 19 setup with SSR, CSR, TailwindCSS 4, and Jest using esbuild

This is a continuation of my first blog post:

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 
Enter fullscreen mode Exit fullscreen mode

Now lets create a esbuild plugin that we can add to our scripts to enable postcss and tailwindcss:

import { readFile } from 'node:fs/promises'; import postcss from 'postcss'; // esbuild Plugin to process css files with postcss export const postcssPlugin = ({ plugins = [] } = {}) => { return { name: 'postcss', setup(build) { build.onLoad({ filter: /\.css$/ }, async (args) => { const raw = await readFile(args.path, 'utf8'); const source = await postcss(plugins).process(raw.toString(), { from: args.path }); return { contents: source.css, loader: 'css' }; }); } }; } export default postcssPlugin; 
Enter fullscreen mode Exit fullscreen mode

In your esbuild configuration now we can use the plugin:

import tailwindcss from '@tailwindcss/postcss'; { //...esbuildConfig, plugins: [ postcssPlugin({ plugins: [ tailwindcss ] }) ] } 
Enter fullscreen mode Exit fullscreen mode

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:

@import "tailwindcss"; @theme { --color-background: #ffffff; --color-foreground: #171717; } @variant dark (&:where(.dark, .dark *)); @layer base { body { @apply text-foreground bg-background; } .dark { --color-background: #0a0a0a; --color-foreground: #ededed; } } 
Enter fullscreen mode Exit fullscreen mode

Configuring Jest

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 
Enter fullscreen mode Exit fullscreen mode

To configure Jest with react and esbuild we'll need to create a transformer to transpile typescript and jsx.

import { transformSync } from 'esbuild'; export default { process(src, filename) { // Ensure only TypeScript and JavaScript files are processed if (/\.(ts|tsx|js|jsx)$/.test(filename)) { const result = transformSync(src, { loader: filename.endsWith('ts') || filename.endsWith('tsx') ? 'tsx' : 'jsx', format: 'esm', // ESM format sourcemap: 'inline', // Inline sourcemaps for debugging target: 'esnext', // Set the target to latest ECMAScript tsconfigRaw: { compilerOptions: { jsx: 'react-jsx' }, } }); return { code: result.code, map: result.map }; } return src; }, }; 
Enter fullscreen mode Exit fullscreen mode

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'; 
Enter fullscreen mode Exit fullscreen mode

Lastly we can create a config file jest.config.json that will use our custom esbuild transformer and setup file.

{ "testMatch": [ "<rootDir>/**/?(*.)+(test).(ts|tsx)" ], "transform": { "^.+\\.(ts|tsx)$": "<rootDir>/scripts/testTransformer.js" }, "setupFilesAfterEnv": [ "<rootDir>/scripts/testSetup.ts" ], "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"], "extensionsToTreatAsEsm": [".ts", ".tsx", ".svg"], "transformIgnorePatterns": ["/node_modules/"], "testEnvironment": "jsdom" } 
Enter fullscreen mode Exit fullscreen mode

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:

GitHub logo willyelm / react-app

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
Enter fullscreen mode Exit fullscreen mode

Top comments (0)