How to Setup a React.js Project From Scratch

Ihan Dilnath
The Startup
Published in
6 min readJan 23, 2021

Hello there. I am excited to post my first Medium article! 🤩 Hope this helps you.

This is a short tutorial to setup a React.js project from scratch, instead of using the create-react-app command which you might be familiar with if you have setup a React project before. By setting up a React.js project from scratch, we can get a deeper understanding on how a React app is setup to mount and render on an HTML file, and how JSX and ES6 syntax (commonly used in React) is made to work on browsers despite the lack of native browser support, especially in the case of JSX. Modern browsers do support ES6 syntax, but to modularize and bundle your code together you need to use additional tools. So, in this tutorial I will cover how you can setup an NPM project and add React to it, how to convert your JSX and ES6 code to backwards-compatible Javascript using Babel, and finally how to bundle your code together using Webpack. Put all of these together, you will have a working React.js project in the end.

Creating an NPM project with React

First we are going to create a folder and setup an NPM project in our project folder. You can do that by executing the following command in the terminal pointing to your project folder.

npm init

The terminal will prompt you for details about the NPM project. You can enter any valid inputs for these fields as you wish.

Once we have initialized an NPM project in our project folder, we should install React and React DOM. React is for building the React components, while React DOM is responsible for rendering React on the browser. We can add these dependencies to our project by executing the following command, in the terminal like before.

npm install react react-dom

Now, we shall create two files: index.html which will be the HTML file that gets render on the browser, and index.js which is the script that will get executed when index.html is rendered.

index.html

index.jsx

So by now, our initial project folder structure is roughly as follows

|< YOUR_PROJECT_FOLDER>
|- index.jsx
|- index.html
|- package.json
|- package-lock.json

Now if we open the HTML file in the browser, we won’t see any output. So let us inspect the console and see if we are getting any errors.

This is because our index.jsx is not defined as an ES6 module and i am using a newer version of Edge (86.x) which uses a Chromium engine that can understand ES6 syntax. You can read more on the solution for this issue in here and here However, fixing this issue alone won’t solve our browser, because of two main reasons:

  1. Even if the browser understands ES6, it does not understand JSX.
  2. Even if my version of Edge can understand ES6, it is not backwards compatible with older browsers.

Due to these reasons, we will have to convert our ES6 + JSX together to a backwards-compatible version of Javascript. This is known as “transpiling”. For this purpose, we will be using Babel.

However, note that using Babel alone won’t work. We will have to use Webpack but the reason will be explained as we go on

Transpiling code using Babel

Babel is a transpiler that is mostly used to convert newer Javascript code (ES6+) to backwards compatible Javascript code which older browsers can support. In the case of this project, we need to convert JSX (React code) into browser supported JS. Let us add Babel to our project.

npm install --save-dev @babel/core @babel/preset-env @babel/preset-react @babel/cli

What are these packages?

  • @babel/core is the core of the Babel compiler
  • @babel/preset-env and @babel/preset-react are Babel presets for transpiling ES6 and React code respecitvely. Babel presets are predefined assembly of Babel plugins suitable for common project types and environments. To know more about Babel plugins and presets, visit here and here.
  • @babel/cli is the package which will install the Babel CLI executable in the node_modules folder. This CLI executable will be used to execute the commands which transpiles the code.

Having installed the Babel dependencies, we shall create a Babel configuration file in the project folder.

babel.config.json

{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"comments": false
}

All what we have done in this JSON is tell Babel that it needs to use the env and react presets. That is all we need to configure Babel with for the time being.

Thereafter, we may execute the Babel compiler executable installed in our node_modules folder by exeucting the following command,

npx babel index.jsx --out-dir lib

This command tells NPX — NPM’s in-built package runner, to run the Babel executable installed in the node_modules folder. What comes after babel are the arguments to the Babel executable, which is the source file ordirectory (index.jsx) and the output file or directory (lib) prepended by the out-dir flag.

The newly transpiled JS can be found in the lib/ folder of your project directory. This is what it looks like,

You can immediately notice that there are no arrow functions or JSX in this file. This is because Babel have transpiled them to a backwards-compatible version of Javascript.

Now, lets modify index.html to point to the transpiled lib/index.js instead of index.jsx.

<!-- <script src="index.jsx"></script> --><!-- REPLACE THE ABOVE IN YOUR CODE
WITH WHAT'S GIVEN BELOW -->

<script src="lib/index.js"></script>

Now, let us run our index.html once again in the browser.

It seems there is no output yet. Let us once again check the console for errors.

We have another error now that says “require is not defined”. If you revisit the transpiled index.js code and observe carefully, you will notice that the code uses the “require” import syntax used for CommonJS modules which are common in Node.JS (if you are familiar with Node.JS). Once again, the browser does not understand the “require” import syntax.

Modularizing and Bundling code using Webpack

So we will use Webpack. Webpack is a tool that bundles Javascript modules together. Let us install Webpack for our project.

npm install webpack webpack-cli --save-dev

Furthermore, to make Babel work with Webpack, we will add the babel-loader Webpack loader.

npm install babel-loader --save-dev

A Webpack loader can be simply understood as a “plugin” of sorts that is used to preprocess files before they are bundled. To know more about loaders, visit the Webpack docs here and the Babel Loader here.

Now let us create a Webpack configuration script with the following:

webpack.config.js

Thereafter, you can run

npx webpack

and Webpack will bundle your JS together and output it to the dist/ folder, where you can find the bundle.js file.

Now, in our index.html, let us use the new bundle.js file,

<!-- <script src="lib/index.js"></script> --><!-- REPLACE THE ABOVE IN YOUR CODE
WITH WHAT'S GIVEN BELOW -->

<script src="dist/bundle.js"></script>

Now let us run the index.html file again …

Et voila! We have React running on the browser 🥳

Congrats! You have successfully setup React.js from scratch 😎 and that is it for this tutorial. You can find the full source code at idl99/setup-react-from-scratch-tutorial (github.com)

In a future tutorial, I will expand on this to setup more features like a Development Server, Hot Module Replacement and more. In the meantime, I look forward to hearing any questions, feedback, or suggestions you may have. Thank you for reading! 🧡

--

--

Ihan Dilnath
The Startup

Senior Software Engineer | Backend-focused Full stack developer | DDD enthusiast