Codementor Events

Step-By-Step: Create a React Project from Scratch

Published Dec 18, 2019Last updated Apr 02, 2021
Step-By-Step: Create a React Project from Scratch

Got no time? Clone the repo and get going!

git clone https://github.com/rajjeet/react-playbook
cd react-playbook/packages/react-basic
npm install
npm start

Creating a very simple React app can be very helpful when you need to try out a specific feature or library. Having this skill is a MUST for learning and mastering React. I will go over the steps for creating a minimalistic React setup in the post. The end result is available on a Github repo.

Step 1: Initialize NPM (Node Package Manager)

mkdir new-react-app
cd new-react-app
npm init --y

We can use the --y to get the basic configuration and scafolding for our Node project.

Step 2: Install React, Webpack, and Babel

npm install react react-dom 
npm install --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin @babel/core babel-loader @babel/preset-env @babel/preset-react

Here's what each package does:
react: UI library for creating modular components
react-dom: enables us to render the React within the browser DOM
webpack: bundler that converts your source code into production-ready output
webpack-cli: allows webpack to work with CLI commands
webpack-dev-server: transforms our source code and serves it on a web server as we develop it continuously. This helps use see the output of your code in the browser.
html-webpack-plugin: an extension to webpack that adds the basic index html file
@babel/core: a JavaScript transpiler to converts modern JavaScript into a production-ready version that's compatible with all browsers.
babel-loader: connects Babel to webpack's build process
@babel/preset-env: group of commonly used Babel plugins bundled into a preset that converts modern JavaScript features into widely compatible syntax
@babel/preset-react: React-specific Babel plugins that convert JSX syntax into plain old JavaScript that browsers can understand

Quick note: --save-dev flag is for partitioning the dependencies into development-specific dependencies, so that they are not included in the production JavaScript bundle

Step 3: Create the files

Let's create the files now.

touch webpack.config.js
mkdir src
cd src
touch index.js
touch index.html

Copy and paste the following code into each file:

This is the webpack configuration. This is the most basic set of configuration details you should get familiar with because it acts as base for the initial setup and further customization.

webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // the output bundle won't be optimized for production but suitable for development
  mode: 'development',
  // the app entry point is /src/index.js
  entry: path.resolve(__dirname, 'src', 'index.js'),
  output: {
  	// the output of the webpack build will be in /dist directory
    path: path.resolve(__dirname, 'dist'),
    // the filename of the JS bundle will be bundle.js
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
      	// for any file with a suffix of js or jsx
        test: /\.jsx?$/,
        // ignore transpiling JavaScript from node_modules as it should be that state
        exclude: /node_modules/,
        // use the babel-loader for transpiling JavaScript to a suitable format
        loader: 'babel-loader',
        options: {
          // attach the presets to the loader (most projects use .babelrc file instead)
          presets: ["@babel/preset-env", "@babel/preset-react"]
        }
      }
    ]
  },
  // add a custom index.html as the template
  plugins: [new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'src', 'index.html') })]
};

I recommend reading the Webpack documentation when you need to evolve this file.

src/index.js
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(<h1>Helloworld React!</h1>, document.getElementById('root'));

This is the app's entry point. It uses the react-dom library to render a heading inside the div with the id root. Whenever we use JSX, we should import the React library. Also, thanks to Babel and the presets, this code is converted to plain old JavaScript in the file bundle file, so that all browsers can comprehend the code.

src/index.html
<html>
  <head>
    <title>Hello world App</title>
  </head>
  <body>
  <div id="root"></div>
  <script src="bundle.js"></script>
  </body>
</html>

Our custom html file with the div tag for injecting React code and script tag for loading the JS bundle.

Step 4: Create NPM run scripts

Modify package.json scripts property to include the following npm scripts:

  // package.json
    ...
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "webpack"
  },
  ...

For production, you should create a seperate config that extends and modifies the development version.

Conclusion

That's it for now. Even after few years of React development, I still come back to this basic project to test my ideas. Frameworks like create-react-app and nextjs are nice for projects, but I like working from scratch for sandboxing.

Here's the Github repo. Enjoy!

Discover and read more posts from Rajjeet Phull
get started
post commentsBe the first to share your opinion
Diwakar Singh
3 years ago

There is not need to include <script src="bundle.js"></script> explicitly in index.html. html-webpack-plugin will add this on its own.

Rafael Gonçalves
3 years ago

Hi! Thanks for sharing this amazing tutorial, but I got a question Why can’t I found the “dist” directory, I mean I saw another tutorial on the internet, and in this tutorial is possible to see how the directory and the bundle file. Thanks again.

Rajjeet Phull
3 years ago

if you run npm run build on root dir, you should see the dist folder.
.
├── README.md
├── dist
├── index.html
├── node_modules
├── package-lock.json
├── package.json
├── src
└── webpack.config.js

Renfrew Chen
3 years ago

Hi Rajjeet! Thank you for your post. With the webpack-cli installed, the following the error with your start script

yarn run v1.22.10
$ webpack-dev-server --open
node:internal/modules/cjs/loader:928
  throw err;
  ^

Error: Cannot find module 'webpack-cli/bin/config-yargs'
Require stack:
- /Users/renfrew/Documents/Projects/test/node_modules/webpack-dev-server/bin/webpack-dev-server.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:925:15)
    at Function.Module._load (node:internal/modules/cjs/loader:769:27)
    at Module.require (node:internal/modules/cjs/loader:997:19)
    at require (node:internal/modules/cjs/helpers:92:18)
    at Object.<anonymous> (/Users/renfrew/Documents/Projects/test/node_modules/webpack-dev-server/bin/webpack-dev-server.js:65:1)
    at Module._compile (node:internal/modules/cjs/loader:1108:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Module.load (node:internal/modules/cjs/loader:973:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Users/renfrew/Documents/Projects/test/node_modules/webpack-dev-server/bin/webpack-dev-server.js'
  ]
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Rajjeet Phull
3 years ago

https://stackoverflow.com/questions/40379139/cannot-find-module-webpack-bin-config-yargs

Do you have the latest webpack version? Do you have webpack-cli installed globally or locally?

Show more replies