Creating a development environment for Node and React (With TypeScript and Webpack)
This is a step-by-step guide with explanations. At the end of the guide, there is sample server-render-ready application that you can use to test your configurations.
After going through these instructions, you will have a simple environment that’s ready for using React applications both on the front-end and the back-end (for server-side rendering). The instructions start with an empty directory and they will guide you through all the dependencies that you need, one-by-one.
Create an empty directory and initialize it with a
package.json file. This file is used in Nodejs projects to store general information about the project (like its name, version, etc) and track what dependencies the project needs (so that anyone can install them all at once).
You can create this file using the
npm init command:
mkdir reactful cd reactful npm init
npm init command will ask you a few questions and you can interactively supply your answers (or press Enter to keep the defaults).
npm init -yto generate your
package.jsonfile with the default values that
npmcan detect about your project (the y is for yes to all questions).
npm init command is done, you should have a
package.json file under your project directory (and nothing else, yet).
package.json file can now be used to "document" any dependencies you need to add to your project. This happens automatically when you
npm install anything.
2. Installing main dependencies
For a Nodejs web server, one popular option to use is Express. You can use it to serve dynamic content under your web server. (You can also use Express to serve static content, but you should consider using a better option for that, like NGINX or a CDN service.)
To add Express to the project:
npm i express
This command will download the
express npm package and place it under a
node_modules folder (which it will create because express is the first package we’re adding). The command will also save this dependency to your
iin the command above is just a shortcut for
The frontend dependencies you need are React and ReactDOM. Add them next:
npm i react react-dom
react-dompackages are not really needed in production because they get bundled into a single file, this guide assumes that you deploy your unbundled code to production and bundle things there. If you want to bundle things in development and push your bundled files to production, you can install these packages - and most of what’s coming next - as development dependencies.
Since you’ll be writing your code in multiple modules (files) and it will depend on other modules (like React), you need a module bundler to translate all these modules into something that can work in all browsers today. You can use Webpack for that job. The packages you need to install now are:
npm i webpack webpack-cli
webpack-clipackage provides the
webpackcommand, which you can use to bundle your modules. The actual Webpack core code is hosted separately under the
Here are the packages you need to make TypeScript do its magic:
npm i typescript ts-loader
typescript package has the core features of TypeScript, and the
ts-loader package provides the loader that Webpack needs to work with TypeScript files.
3. Installing development dependencies
The following are dependencies that are not needed in production. To track them separately, you can use the npm
-D install flag to save them under a
devDependencies section in
When you run a Node server and then change the code of that server, you need to restart Node. This will be a frustrating thing in development. Luckily, there are some workarounds. A good option for a TypeScript project is ts-node-dev:
npm i -D ts-node-dev
This package will make the
tsnd command available in your project. That command runs your Node server in a wrapper process that monitors the main process and automatically restarts it when files are saved to the disk. Simple and powerful!
Another priceless development dependency is ESLint. DO NOT SKIP THIS ONE!
ESLint is a code quality tool and if you don’t use it, your code will not be as good as it could be.
Since TypeScript is part of this stack, you need to configure ESLint to parse through what TypeScript is going to parse through. You should also use the main recommended ESLint configurations in addition to those recommended for React projects. Here are the packages you need for that:
npm i -D eslint @typescript-eslint/parser \ eslint-plugin-react eslint-plugin-react-hooks
To configure ESLint, you need to add a
.eslintrc.js file in the root of the project. This file will naturally depend on your code style preferences, but definitely start it with the recommended configurations and then customize them as needed:
The most popular testing library that’s usually used with React is Jest. You’ll also need
ts-jest to make jest work with TypeScript files:
npm i -D jest ts-jest
4. Creating an initial directory structure
This really depends on your style and preferences, but a simple structure would be something like:
reactful/ dist/ main.js src/ index.tsx components/ app.tsx server/ server.tsx
Note how I am using the
.tsx extension for files under src. This signals to TypeScript that these files might include the JSX syntax. By using this file extension, we don’t need to do any further configuration for compiling JSX!
Use conventions over configurations when you can. It’s not just about using the conventions of a fraework (or library). You should make your own code leverage this very powerful concepts.
5. Configuring Webpack and TypeScript
tsconfig.js file under the root of the project and put the following
module.exports object in it:
To configure Webpack to bundle your application into a single bundle file, create a
webpack.config.js file under the root of the project and put the following
module.exports object in it:
dist/main.js. If you want to change that, you’ll need to configure the
outputproperty in the config object.
6. Creating npm scripts for development
You need 2 commands to run this environment. You need to run your web server and you need to run Webpack to bundle the frontend application for browsers. You can use npm scripts to manage these.
package.json file, there is a
scripts section. If you generated the file with the
npm init defaults you’ll have a placeholder "test" script in there. Change that to work with Jest:
Now, add 2 more scripts in there. The first script is to run the server file with
tsnd. You can name the script anything. For example:
"dev:server": "tsnd --files --respawn src/server/server.tsx --ignore-watch node_modules,dist"
dist/directory when restarting Node automatically as changes in the
dist/directory are driven by changes in the
src/directory, which is already monitored.
The other script that you need is a simple runner for Webpack:
"dev:bundler": "webpack -w --mode=development"
-w flag in the command above is to run Webpack in watch mode as well and the
--mode=development flag is to make Webpack generate a development-friendly bundle.
Here’s the whole
scripts section in
package.json after adding these 2 new dev tasks (note the commas):
7. Testing everything with a sample application
At this point, you are ready for your own code. If you followed the exact configurations above, you’ll need to place your
ReactDOM.render call (or
.hydrateRoot for SSR code) in
src/index.tsx and serve
dist/main.js in your root HTML response.
Here is a sample server-side ready React application that you can test with:
That’s it. If you run both npm
dev:bundler scripts (in 2 separate terminals):
npm run dev:server npm run dev:bundler