How You Should Create React Applications in 2023 — Part 1

Murat Çelik
Beyn Technology
Published in
5 min readDec 21, 2022

Hello everyone. 👋

I will basically show you how I create my react applications and its structure from scratch. This article is not just basically run simple npm command on terminal and create a basic application. In this article, it is about creating a the codebase with linting rules and other configurations.

Let’s start with creating a simple react application with Vite. I prefer creating React applications with Vite over Create React App because of advantages such as faster build time, better performance etc. Let’s run npm create vite@latest in our terminal and start creating our project.

npm create vite@latest

--- (Answer the prompted questions as below) ---

- Select a framework
+ React

- Select a variant
+ TypeScript

After creating your project, do not forget to install dependencies with npm install command.

Absolute Paths

First thing I like to do in these clean projects is do necessary configurations to be able to use absolute path feature. It basically allows us to make clean import statements.

import Button from '../../components/Button'; // Normal Way
import Button from 'components/Button'; // Absolute Path Way

To be able to do this, let’s open our tsconfig.json file and set baseUrl as src folder in compilerOptions.

{
"compilerOptions": {
// your other configurations
"baseUrl": "src"
}
}

Also we need to tell Vite how to build import paths. We are going to install a plugin called vite-tsconfig-paths and add it into our plugins in vite.config.ts.

npm install vite-tsconfig-paths --save-dev
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths'; // --> import it

export default defineConfig({
plugins: [react(), tsconfigPaths()], // --> add here
});

ESLint, Prettier, Husky and Lint Staged

If you are in this article, you probably know what these tools and their benefits. But to summarize briefly, you can scan your code and find problems with ESLint, format your code as you like with Prettier and create git hooks with Husky. We are going to create a job that will run our rules and code formatting standards and then we are going to create a pre-commit hook with husky to run this job before every commit. At that point, we will use Lint Staged to prevent commit if any error occurs.

Let’s start with installing dependencies for eslint and prettier configurations.

npm install eslint prettier eslint-config-prettier --save-dev

And now we need to initialize our eslint configuration file.

npx eslint --init

--- (Answer the prompted questions as below) ---

- How would you like to use ESLint?
+ To check syntax, find problems, and enforce code style

- What type of modules does your project use?
+ JavaScript modules (import/export)

- Which framework does your project use?
+ React

- Does your project use TypeScript?
+ Yes

- Where does your code run?
+ Browser

How would you like to define a style for your project?
(Rest of the answers are up to you. You can either choose a popular style guide or create your own.)

After creating .eslintrc.json file, it should look like this. You can install other popular style guide plugins such as Airbnb etc.

{
"env": {
"browser": true,
"es2021": true
},
"settings": {
"react": {
"version": "detect"
}
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"prettier" // --> Add this line
],
"overrides": [],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint"],
"rules": {
"react/react-in-jsx-scope": "off"
}
}

Let’s create our configuration file for Prettier. Create a file named .prettierrc.json and set formatting rules as you wish. Here is mine:

{
"bracketSpacing": true,
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 3
}

Now, we are going to create a pre-commit hook and make this command work before every commit and to do that, we need to initialize husky at first.

npx husky-init && npm install

After running this command, you will see a folder named .husky and pre-commit file inside of it. We need to replace last command in this file with npx lint-staged. It should look like this at the end.

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

Finally, we need to make Lint Staged configurations in package.json.

{
...
"lint-staged": {
"**/*.{js,jsx,ts,tsx}": [
"npx eslint --fix",
"npx prettier --write"
]
}
}

From now on, these jobs will run in every commit and prevent it if any error occurs. We can test it by creating some commits.

Commitizen

Finally, we are going to set up commitizen which is a tool that helps you write better commit messages by filling required fields in prompting window when you try to commit.

First of all, you need to install commitizen cli globally in your computer.

npm install -g commitizen

Next, you need to make your project commitizen friendly.

commitizen init cz-conventional-changelog --save-dev --save-exact

Now if you stage some files and run cz command in your terminal, you will see prompted window like below.

You can fill the required fields according to selected option and then you will have better commit messages like below.

Date:   Wed Dec 14 11:00:17 2022 +0300

feat: setting up commitizen

installing commitizen to make more readable commit messages

#123

Styling

We are going to use CSS modules to style our application. CSS modules are basically a solution for fixing global scope problem by scoping all class and animation names locally. Besides, we will use it SCSS with CSS modules to use power of nesting, mixins and etc.

First of all, we need to install sass preprocessor.

npm install sass

And now we can use CSS modules without doing any configuration thanks to Vite. Only thing we need to do is creating a file with *.module.scss.

Let’s create a folder named components and another folder named as button inside of it. In button folder, create a file named Button.module.scss and write your styles same way as css.

.button {
background-color: gray;

.label {
color: white;
}
}

Create another file Button.tsx and import your styles then use it like this.

import buttonStyles from 'components/button/Button.module.scss';

const Button = () => {
return (
<button className={buttonStyles.button}>
<span className={buttonStyles.label}>Button</span>
</button>
);
};

export default Button;

Conclusion

Now you are able create your components and style them with CSS modules, use them with fancy way of importing which is Absolute Paths, write clean codes thanks to configurations that we have done with ESLint and Prettier and make your meaningful and fancy commits by using Commitizen.

In the next parts, we will cover routing, theming, global state management and so on.

See you guys on next parts soon! 😊

--

--