DEV Community

Cover image for 5 Good practices to scale your React projects easily
Jeffrey Yu
Jeffrey Yu

Posted on

5 Good practices to scale your React projects easily

For most React developers, it's easy to just get our hands on writting new lines of code. However, we sometimes missed keeping them organized and planned for future use as the project scales.

Having a plan for scaling can help you:

  1. Reuse and reduce development time
  2. Organize project and prevent project reconstructions
  3. Show you are good developer by taking consideration of the project and other devs :)

Here are 5 lessons I learned from scaling my React projects. They help me to plan ahead for my projects while writting pretty React code.

1. Always start with state management

When a project was small, I jumped right into writing state for individual components. However, it got messy when I wanted to sync up states for several components and tried to to use props and callback functions.

Always start with a state mangement tool, whether it's Redux, Recoil, or context and hooks. Even if a project is small, you'll need Authenticaiton and Alert to be managed globally.

React state managment

Besides, state management seperates logic from components. When handling backend calls, it serves like a controller/service layer between UI and database. State and actions in this layer can be reused across many components.

A tip here is always track waiting status for backend calls for conditional component rendering. It saves you from unnecessary errors and a nice loading spinner shown to the user.

2. Make your own component library

I found that even when I'm using a UI library like Material UI, I still need customization on props, logics, and styles for my project.

Create a custom components library allowed me to reuse them across pages and even exported to other projects.

Include styles, tests, types, and Storybook templates (recommended) for each custom component. A good practice is to organize the library in atomic design like the following.

├── atoms
│   └── CustomButton
│       ├── CustomButton.tsx
│       ├── CustomButton.types.tsx
│       ├── CustomButton.styles.tsx  
│       ├── CustomButton.test.tsx
│       ├── CustomButton.stories.tsx
│       └── index.tsx
├── molecules
│   └── CustomDialog
└── organizations
    └── CustomTable
Enter fullscreen mode Exit fullscreen mode

3. Define types

As we know, JavaScript is dynamic-typed language. When a project scales, props passed across components and functions increases.

If there is no type checking, many unnecessary errors involving edge cases like null and undefined could happen. Define types also increase readibility of code.

It's better to start with or migrate to TypeScript if possible, but define PropTypes also works.

4. Use global AND specific styles

Styling is always a big headache for frontend devs. We have to handle both unified styles and individual styles.

CSS meme

If a project has UI design provided like Figma, try to define styles in global theme first. It's better to define them in the theme provider of a UI library to easily make customization on defined palettes. The theme provider also handles light & dark themes for you.

For styles of individual components, try to include them in custom components library mentioned above. If they are specific to one component, include them in a styles file under that component.

The rule of thumb is to include styles at the top level needed for reuse.

5. Sync pages folder with routes

Previously, I made pages and components folders quite a mess, keeping two in only either one folder.

Then I learned that it's better to organize the pages folder in sync with the routes. This increases readability for other devs to understand the website structure, like the following.

├── events
│   ├── index.tsx
│   └── event
│       ├── index.tsx
└── user
    └── index.tsx
Enter fullscreen mode Exit fullscreen mode

events correspondes to /events, and event correspondes to /events/:id.

I'm having the same structure for the components folder to correspond components to a page where they are used. But you can also have a /components folder under each page, and make the components folder for other use.

These are my good practices on planning a React project for scale, and everyone has their own way. The two rules of thumb to conclude these good practices are:

1. Seperate & Reuse
2. Organize for readability

Happy coding! 🚀

Top comments (34)

dikamilo profile image

Always start with state management

I will add here: abstract here from your current state management tool. Create custom hooks that will provide data. It will be easy to change from for example React providers to Redux when needed just by replacing logic in custom hooks and not refactor every component.

jeffreythecoder profile image
Jeffrey Yu

Great advice! It's clean to wrap hooks like useSelector, useEffect and useMemo in a custom hook and not in the component.

agnel profile image
Agnel Waghela

Hi, @dikamilo, can provide an example? I would like to get a clear idea through it.


jeffreythecoder profile image
Jeffrey Yu • Edited

Yes Tamas, frontend scaling is different than backend. Here I'm talking about how to scale code (size of client app), where modular and extendable code are the keys.

For handling more load like scaling backend, frontend can apply caching and reducing unnecessary requests to backend. Server-side rendered clients could have more cases.

omercohen990 profile image

Also code splitting is pretty important for frontend scaling

marwababelly profile image

Thanks for sharing 😊👏

d4rthv4d3r profile image
Julián Chamalé

Great article, however I disagree with the atomic design as it's not intuitive and building it on top of a library makes it confusing. I prefer the material-ui approach for organizing code in inputs, display, etc.

jeffreythecoder profile image
Jeffrey Yu

That's a good way to organize too! Thanks for suggesting

andrewbaisden profile image
Andrew Baisden

Good article and I agree having a good state management from the start will make your life easier on when the codebase grows.

israelmitolu profile image

Great article! These are solid points

zeffk profile image
Huzaif Qazi

I really liked the atomic design practice 🖤

lyavale95 profile image

Me too

madza profile image

wonderful read

madza profile image

a great article indeed 👍💯✨

wilmela profile image

Nice write up. Thanks for sharing.

rafaelcg profile image
Rafael Corrêa Gomes

Awesome tips, thanks for sharing them!

rkallan profile image

I like your point to create your own ui library.

ironcladdev profile image
Conner Ow

Awesome advice, will take note of when I make my next react app!

etnan profile image

Thanks, Jeffrey! Awesome tips.

elsyng profile image

I'll respectfully disagree :o).

For me React is about seeing "component", as opposed to seeing "global". For me React is component-based programming

That includes: state management and styling. I'd avoid anything global as much as possible, and make a component independent (non-sharing) as much as possible.

(Forget folder hierarchies. Stick to a single level of folders as much as possible, such as: components, hooks, pages. The modern IDE's will find the file for you. I think folder trees cause duplication and redundancy.)

jeffreythecoder profile image
Jeffrey Yu

The main reason for doing state management and styling globally is to allow reuse and easier modification in one place.

If you don't do state managment, you still need to communicate state between components, which don't make them independent but coupled. And seperating the logic to handle state and backend calls from components makes the logic independent to use by various components.

Folder hierarchies makes better readibility, but it's really a good pratice where it doesn't impact performance so it's your choice to use it or not.

za5dwunasta profile image
Magdalena Motyl

Yes, fully agree :) Styles and states IMHO should stay as close to the component that needs it as possible, as long as possible.
It reduces the number of rerenders + it is easier to flexibly reuse components.

If you start coupling components with a global state/store sooner or later you won't be able to reuse it in any part of the app that does not use the same global store. And then decoupling it might be a nightmare.