The Ultimate React Project Setup

HTML code background with React logo on top
React: a super popular way of creating modern and efficient websites.

Having a good project setup is really important — without it, it’ll be really hard to maintain and build upon your projects. Of course, at the end of the day, it all comes down to personal preference (or maybe your team’s guidelines). Let’s jump into what I believe to be the ultimate React setup! Feel free to give it a try and let me know how you like it! 🔥

Creating the app

To start off, create a new React application using our favorite tool: create-react-app.

$ npx create-react-app my-app --template typescript

I highly recommend to work with TypeScript. There are many benefits of using TypeScript over regular JavaScript when working with React, some of which are:

  • Drastically improved readability and understanding of code
  • Catch errors beforehand
  • Intelligent code autocompletion

Of course using TypeScript isn’t required, you can still work with regular JavaScript and be just fine. But if you haven’t tried using TypeScript yet, you definitely should give it a try. You won’t regret it!

🔗 Read about how you can add TypeScript to your React project from the official docs.

Making use of SCSS

Now, this step is optional. I myself prefer to work with SCSS rather than CSS, since it’s more pleasant to work with and it’s super easy to implement it! But don’t worry, your React application will look just as good if you choose to use CSS instead.

If you’d like to use SCSS like I do, simply install it using NPM:

$ npm install node-sass --save

That’s it! You can write your styles with SCSS now! 👍

Oh, and a quick side note: you can use absolute imports in SCSS as well! There’s no need to navigate two, three or more folders up to reach some partial files. You can simply start in the src directory by importing like this:

@import "/src/path/to/partial_file";

Let’s move on to the directory structure, shall we?

Directory structure

The way your directories are structured is very important. After experimenting for quite a while, I came up with a solution that works really good — at least for me and a handful of other people.

.
├── /node_modules
├── /public
├── /src
│ ├── /components
│ │ ├── /box
│ │ ├── /container
│ │ └── ...
│ ├── /scss
│ ├── /views
│ │ ├── /home
│ │ ├── /login
│ │ ├── /notFound
│ │ └── ...
│ └── index.tsx
├── .gitignore
├── README.md
└── tsconfig.json

Let’s quickly go over the individual folders and explain their purpose.

  • components: this directory holds all components our React app consists of. Each component has its own folder within the components directory.
  • scss: Inside this directory you’ll find your SCSS files. I place my main style (index.scss) and partial files (like _variables.scss and _typography.scss) in there.
  • views: This directory holds the individual pages our React application has. Just like components, each view has its own folder within the views directory.

From here on in, the directory structure can be built upon however you like. You’re free to add folders for different libraries you’re using. I do it all the time. Whenever I need to use state management tools, Recoil.js is my go-to library for this. I then create another directory called recoil for my atoms and selectors. You can do the same for Redux reducers, for example.

With a huge structure like that, a problem you’re most likely fimiliar with is sure to come… import hell! 🙄

Avoiding import hell

You surely had come across a moment in which you had to move through five different directories to import some other file. I have.

import { something } from "../../some/deep/module";

I cannot tell you enough how much I disliked seeing these long import statements in my code. They made the code look so much more… unclear!
Fortunately there’s a perfect solution to this ugly problem, and it’s called module aliases. Yes, you can create your own aliases for modules and import different files and modules by using them!

import { something } from "@deep/module";

Doesn’t that look so much better now? Of course! So let’s get to configuring our React project so we can use custom module aliases. 😀

For this we need to access the Webpack config files. We can’t do that unless we eject by running npm run eject, but that is an unrecommended practice.
A much better way to edit Webpack config files is to use a tool like Craco.

You can install Craco (and the plugin we need) using NPM:

$ npm install @craco/craco --save$ npm install craco-alias --save-dev

Now, after Craco and the plugin are successfully installed in our project, we can create the configuration file for Craco. Simply create a file called craco.config.js in your project’s root.

Well done! We’re done with Craco here. Now we need to do some little extra steps, so our module aliases actually work.

Create a file called tsconfig.paths.json in your project’s root. You can define all your custom aliases inside this file — specifically inside the paths object.

💥 Note the slash and asterisk after each alias. These are important, so IntelliSense can use other directories and files within that folder you specified!

Good, we’re almost finished. Open up tsconfig.json and add this single line to the top:

"extends": "./tsconfig.paths.json", 👈
"compilerOptions": {
...
}

Finally, edit the scripts section of your package.json, so it looks like this:

"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
}

You can leave the eject script like it is, because we don’t need to eject and it serves no real purpose to us.

In case you’re wondering, “why don’t we add the paths to tsconfig.json? Why do we have to use tools like Craco?” As of now, applications created with create-react-app do not support module aliases by default. Until we can add aliases directly to tsconfig.json, we need to resort to solutions like this one.

Wonderful! You’re ready to go and create an awesome React application! 😎
Have you used a similar setup before? If not, give this one a try and let me know how you like it! And of course, if you have any questions, just ask them, I’m here to help after all.

If you have Instagram, don’t miss my content on there! 🔥

Hello! 👋 I aim to make understanding JavaScript as easy as possible! Check out my Instagram page too, that's were I post a lot of valuable content! 🧠

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store