Starting a React Project in 2024: Best Practices & Tools
Stay ahead in 2024 with the latest tools and best practices for React development. From choosing between JavaScript and TypeScript to leveraging modern build tools like Vite, this guide covers everything you need to know to build efficient, scalable React applications.

React continues to be a dominant force in front-end development, and staying updated with the latest practices and tools is crucial for building efficient, scalable applications. Whether youβre starting a new project or looking to refresh your React skills, this guide will walk you through the best practices and essential tools you should use in 2024.
React's ecosystem is ever-evolving, and keeping pace with its latest tools and best practices ensures you build high-quality applications. In this post, weβll explore the most effective ways to set up a React project, to help you create robust and maintainable applications.
1. JavaScript v/s Typescript
When starting a React project, choosing between JavaScript and TypeScript is crucial:

- JavaScript: Quick setup, flexible, and widely supported. But it has no type safety by default, which can lead to runtime errors and make large projects harder to maintain.
- TypeScript: Adds static typing, reducing bugs and improving code quality. Better tooling and scalability for large projects. But it has a slightly steeper learning curve, longer setup, and added complexity for smaller projects.
But, if you really want to stick with JavaScript, you can achieve some level of type safety using the prop-types. This is a built-in feature in React that allows you to enforce type-checking on your components' props
2. Choosing a Package Manager
A package manager is a tool you'll rely on throughout the development process to manage your project's dependencies, scripts, and workflows. The right package manager can streamline your development, reduce friction, and ensure consistency across your team.

- npm: This is the old school default package manager for Node.js, requiring no additional setup. This is the most widely used package manager and hence it has a lot of community support. But, it is getting slower and there are better options.
- yarn: It is developed by Facebook, is designed to address some of the limitations of npm, the default package manager for Node.js. Yarn is known for its speed, reliability, and additional features that make it a strong contender in the package manager space.
- pnpm: pnpm uses a unique symlink system, saving disk space by sharing packages across projects. Like Yarn, pnpm offers fast installation times and efficient package management. But requires a little bit of internal knowledge of how things are working under the hood.
3. Bootstraping a React Project
Bootstraping or Scaffolding means getting the initial setup for React. Then we build our Application on this setup. This abstracts away most of the things such bundler setup and gives us a clean starter project. Let's discuss what are the ways of scaffolding a react project.
- Create React App { CRA }: It is the most popular and straightforward way to bootstrap a React project. Developed by Facebook and is no longer maintained { since 2023 }, CRA provides a powerful and opinionated setup with minimal configuration required. This is not so fast to be honest and has limitations.
// using yarn
yarn create react-app my-app --template typescript
// using npm
npx create-react-app my-app --template typescript
- Vite: This is better option and probably the best option to start a React Project without using any frameworks { like NextJS, Remix }. This is faster that CRA, and uses ES Build internally.
If you want to know more about this topic, check out this post.

4. Essential Development Tools
To maintain high code quality, consistency, and efficiency in your React projects, itβs crucial to set up a few key development tools. These tools help automate tedious tasks, enforce coding standards, and streamline your workflow, ensuring that your codebase remains clean and maintainable.

- Prettier - Code Formatting
Ensures that all code follows the same style, regardless of who wrote it. It helps to maintain consistency across the codebase where multiple people are working together.
- ESLint - Code Linting
It helps in identifying and fixing problems in your JavaScript code. It also helps enforce a consistent style guide and catches potential bugs by analyzing your code for common issues and deviations from best practices.
eslint-plugin-prettier
.- Husky - Git Hooks
It is a tool that lets you run scripts in your Git hooks, which are actions triggered at specific points in the Git workflow. This is particularly useful for automating tasks like running tests, linting code, or formatting code before commits are made.
5. ts/js or tsx/jsx: Choosing the File Extensions
Often, developers default to using .js
for all files in a React project, whether they are writing pure functions or React components. However, choosing the correct file extension not only helps organize your code but also ensures that your development environment provides the appropriate tooling and type-checking capabilities.
JS/TS: Pure Functions and Non-React Code
- JavaScript (.js): Use
.js
for files that contain pure JavaScript functions or logic that doesn't involve React. These could be utility functions, API handlers, or other business logic. - TypeScript (.ts): Similarly, use
.ts
for TypeScript files that donβt include any React code or JSX syntax. This is ideal for leveraging TypeScriptβs type-checking in your pure functions or logic files.
JSX/TSX: React Components
- JavaScript with JSX (.jsx): Use
.jsx
for files that include React components written in JavaScript. This extension indicates that the file contains JSX syntax, helping your editor provide the right support and tools. - TypeScript with JSX (.tsx): Use
.tsx
for React components written in TypeScript. This allows you to benefit from TypeScriptβs powerful type-checking while working with JSX to define your UI.
It will help organize the codebase. It helps differentiate between pure logic files and those that are React-specific. Next time you make a react project don't just use .js for all the files. Alright ?
6. Choosing a styling framework
Styling your React components is a crucial aspect of building visually appealing and maintainable applications. When it comes to styling in JSX, there are several options available, each with its strengths and best use cases. Letβs explore some of the most popular choices, so you can decide which one best suits your project.
- Normal CSS
It is the traditional approach to styling. You write CSS rules in separate.css
files and import them into your React components.
Component:
// Button.jsx
import './Button.css';
const Button = () => <button className="btn">Click Me</button>;
// Button.css
.btn {
background-color: blue;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
}
This is very familiar to all of you but it's completely a nuisance and It will create conflicting styles because the style is global.
- CSS with Modules
It allows you to write CSS with scoped class names, avoiding global conflicts. Each class name is automatically scoped to the component.
// Button.jsx
import styles from './Button.module.css';
const Button = () => <button className={styles.btn}>Click Me</button>;
// Button.module.css
.btn {
background-color: blue;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
}
This is a better way of writing plain CSS with react, because now we have scoped css and not global.
- SASS
It is a CSS preprocessor { another good example is LESS } that adds features like variables, nesting, and mixins. It makes your CSS more powerful and maintainable.
// Button.jsx
import './Button.scss';
const Button = () => <button className="btn">Click Me</button>;
// Button.scss
$btn-bg: blue;
$btn-color: white;
.btn {
background-color: $btn-bg;
color: $btn-color;
padding: 10px 20px;
border: none;
border-radius: 4px;
}
This is same as CSS but with a lot more features added on top of it. It can have a learning curve
- Tailwind
This is my personal favourite way of styling in React. Tailwind CSS is a utility-first CSS framework. It provides predefined classes that you apply directly to your JSX for styling.
// Button.jsx
const Button = () => (
<button className="bg-blue-500 text-white py-2 px-4 rounded">
ClickMe
</button>
);
7. UI Frameworks and Libraries
When building user interfaces for React applications, leveraging a UI framework or library can significantly speed up development and ensure a polished, consistent look and feel. Hereβs a quick overview of some popular UI frameworks and libraries to consider:

- Material UI: It is a popular React component library that implements Googleβs Material Design system. It provides a comprehensive set of pre-designed components and styles, making it easy to create modern and responsive UIs.
- ShadCN: It is a newer UI library designed to be lightweight, flexible, and modern. It emphasizes simplicity and developer experience, providing a clean and customizable set of components.
8. State Management
Basically, there are two kinds of states in a React Application.

- Client State: refers to the data that is managed and maintained within the client-side application, typically using Reactβs state management tools. This includes UI-related data like form inputs, toggle states, or local component state.
- Server State: pertains to the data that originates from an external server and needs to be synchronized with the client-side application. This state is typically fetched from APIs or other data sources and often requires managing loading states, error handling, and synchronization.
9. Handling HTTP Requests
When working with data fetching and server communication in React, you typically use one of two approaches: Axios or the built-in Fetch API. Hereβs a brief overview of each:
- Axios is a popular JavaScript library for making HTTP requests. It simplifies the process of sending requests and handling responses, and it comes with several useful features out of the box. It is promise-based and also has interceptors which is an useful feature in some scenarios.
import axios from 'axios';
const fetchData = async () => {
try {
const response = await axios.get('https://api.example.com/data');
console.log(response.data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
- Fetch API is a built-in JavaScript API for making HTTP requests. It provides a simple way to perform network requests and handle responses directly within JavaScript.
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('Network response was not ok');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
10. Testing Libraries
When it comes to testing React applications, you generally use different tools for different types of tests. Jest and Cypress are two popular choices, each serving distinct purposes:

- Jest
It is a widely-used JavaScript testing framework primarily for unit testing. It is designed to ensure that individual components or functions work as expected.
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
test('renders the component', () => {
render(<MyComponent />);
expect(screen.getByText('Hello World')).toBeInTheDocument();
});
- Cypress
It is an end-to-end testing framework designed for integration testing. It focuses on testing the entire application flow, from the user interface down to the back-end.
describe('MyComponent', () => {
it('should display the correct text', () => {
cy.visit('/my-component');
cy.contains('Hello World').should('be.visible');
});
});
11. Directory Structure
Having a clean directory structure is important for the scaling and maintainability of the code. Ofcourse, you don't want to find in which file and where you had written a function { search feature can help, still it's important }.
my-react-app/
βββ src/
β βββ assets/
β βββ components/
β βββ pages/
β βββ queries/
β βββ stores/
β βββ services/
β βββ utils/
β βββ styles/
β βββ types/
β βββ tests/
β β βββ unit/
β β βββ e2e/
β βββ App.tsx
β βββ index.tsx
β βββ tsconfig.json
βββ .eslintrc.js
βββ .prettierrc
βββ .husky/
β βββ pre-commit
βββ package.json
βββ yarn.lock
The above directory structure will give you a comprehensive structure for organizing different files and logic in your React application.
Whooof! That was quite a long blog. Isn't it? Well, I think if you have reached this far, it will be worth it for you. You have gained a lot of useful information that will also be fruitful in your next project and career.
That's it for today, I hope you find it useful. Stay subscribed to get the latest updates.