DEV Community

Jaakko
Jaakko

Posted on

How I structure my React.js projects

Structuring React applications into files and folders is an opinionated topic, because there is no right or wrong way to do it. I decided to share how I have structured my projects lately.

Warning: Highly opinionated!

Let's get started.

Single file

React projects usually start with an src/ folder and one src/App.tsx file with an App component.

1

At some point, your app has more features, more lines, and you will need to make smaller standalone components:

2

Sometimes it's OK to have multiple components in one file, especially if those components are tightly coupled to the main component. Often it's better to use multiple files because eventually, that one file is not sufficient anymore.

Multiple files

Instead of having all our code in one file, we can split these components into multiple files. At this point, as our project is still quite small, I would do it like this:

3

In the above example, List component exports only List, but it also has the ListItem component, which is not exported.

If you want to take it to the next level, you can start using directories instead of files. I would also extract the ListItem from List and make it its own standalone component inside src/components/List/partials subdirectory:

Image description

From now on, I would only use /components directory for reusable components.

Folder separation

Next, we separate features from components. Let's say we need to create an useUser hook, so we'll create a dedicated hooks directory and put it in there:

4

That hooks folder is meant for reusable hooks only. If you have a hook that is used by one component only, it should remain in the component's own file (or directory).

That same principle applies to many other things as well. For example, if we need to create a reusable service - we'll create a services directory and put our service in there:

5

Separated views

When we create separate directories for everything that's reusable and keep the non-reusable stuff only where it is used, we've come a long way.

Lastly, I want to create a directory called views. Those views are basically a representation of the url. For example, a directory User could mean https://<url>/user and so on.

These views can of course import reusable services or components, but they also have their own subdirectories for non-reusable stuff.

Here's an example, how my project structure could look like:

6

Follow on Twitter for more: https://twitter.com/bjakyt

Oldest comments (25)

Collapse
 
nikolicstjepan profile image
Nikolić Stjepan

This makes perfect sense, thanks for sharing :)

Collapse
 
bjakyt profile image
Jaakko

You’re welcome!

Collapse
 
jeydotc profile image
Jeysson Guevara

Finally one which is easy to follow :)

Collapse
 
bjakyt profile image
Jaakko

Thanks!

Collapse
 
standiki profile image
Stanley Diki

Awesome. Nice structure. What's your editor and themes?

Collapse
 
bjakyt profile image
Jaakko

Hey, I used ray.so/ for the images.

Collapse
 
standiki profile image
Stanley Diki

Thanks for this. I appreciate.

Collapse
 
briansanteliz profile image
Brian Santeliz

Excellent, Thanks!

Collapse
 
bjakyt profile image
Jaakko

You’re welcome!

Collapse
 
peterwitham profile image
Peter Witham

Nice and clean, I try to keep the root folder of a project clean and empty so my brain can start there and then dive into the area of interest as I go.

Collapse
 
huykonofficial profile image
Huy Kon

why you don't share a git repo?

Collapse
 
ceoshikhar profile image
Shikhar

Clean Architecture for the win.

Collapse
 
ksixen profile image
Altaev Nurzhan

What about css files? Where need to place it?

Collapse
 
madhan_s profile image
Madhan S

CSS/ SASS should be split per component basis and placed in the corresponding component folder with same name as of component (i.e. Header.tsx and Header.css should be placed in src/components/Header) . Global styles or themes should be placed in src/styles folder.

Collapse
 
insidewhy profile image
insidewhy • Edited

Organise by feature, not by nature. Putting all your components in one directory and your hooks in another doesn't make sense. One feature will be split across multiple top level directories. I don't know why people organise this way in react when you don't see it in almost any other framework (for good reason).

Collapse
 
vitalybaev profile image
Vitaly Baev

Agree, you could take a look at awesome architecture for frontend projects: feature-sliced.design/en

Collapse
 
paweldotio profile image
typical pawel

I agree with @insidewhy . I've seen a lot of projects organised by nature, not by feature which makes future maintenance really hard not only from the perspective of having a massive folder with components but also moving them around between different projects.

Collapse
 
joset98 profile image
joset98

Hey morning dude, do you have a project example ? have nice day ;)

Thread Thread
 
paweldotio profile image
typical pawel • Edited

I do not have a project example for your unfortunately because all of them would still be under NDA right now. Nevertheless, to give you a little bit of an idea consider the explanation below. The main distinction here is the difference between organising your projects vertically (per feature), horizontally (per function eg. components, services etc.) or finding some solution in the middle (reusable elements per function, rest per feature).

Organising your projects horizontally is completely fine if your app is not overly big. Unfortunately as a project grows what happens very often is that the components folder (let's use this one as an example) will become a massive flat-structured dump for all the components that you have in the app. Other folders like services, data, hooks thingies or whatever you use as layers in your app will follow the forlorn fate of the components folder. What you end up is a basically a pile of latkes. Not only React front-end apps suffer from this issue - I have seem this problem appear in NodeJS and iOS apps as well. This is not great for the following reasons:

  • Imagine you're a new developer joining the team. A junior one to use an edge case. You will end up having to navigate through all of the latke layers to solve one simple task that has been assigned to you. The learning curve is much steeper and probability that you will make mistakes in the beginning is much higher.

  • Imagine you've got a request to remove a feature. Instead of getting rid of one folder, you need to slice through each single of the latkes that you have there. In the best case you'll be removing some files from a couple folders. In the worst one, removing tons of related dependencies. The worst case is an equivalent of someone putting a lot of long curly hair into your latkes mixture.

  • Imagine an entire feature that's in your app (for example - authentication, some calculator that you might have there or any other reusable feature) suddenly needs to be used in another project. This happens surprisingly often if you work within an organisation that has multiple teams using similar tech. If you're stuck with the folder structure of components / hooks / services. etc, you will have to move each one of them one by one in the best case.

The list goes on, those are just some examples.

To reiterate on the previous point - do what's best for you and your project and the team that you're working with. There is not single grand truth that will tell you how each project in the whole wide universe should be organised. If you expect the app to grow or have components of views / business logic that are reusable sticking to a horizontal structure will make you more miserable than you need to be. We don't want that.

It's not all black and white though and there are some solutions that could place itself in the middle. One could use the following heuristic - is a the component used more than once? If yes, put it in the components folder, if not stick with a folder structure that puts a clear division between different features of the app.

Collapse
 
victorocna profile image
Victor Ocnarescu

Maybe it's better to organize by both. How about a generic hook like useModal that can be used by ANY modal in your project. Isn't organizing it by nature a better model than anything else?

Collapse
 
insidewhy profile image
insidewhy

Add it to an open source library or a utils folder in the root or even modals or utils/modals. Not hooks folder. At my current job we use a monorepo and have subpackages for things like this so we can share generic functionality with many projects.

Collapse
 
goodnewsj62 profile image
Goodnews

Nice one but i think project should be organised by feature (responsibility principle) and i also belive in the KISS principle.

Collapse
 
ronaldscruz profile image
Ronald S. Cruz

I don't agree with the idea of keeping partial components inside the main component. Even if the partial component is small, I would rather to have a standard, to make the project structure more legible :D
But I loved these ideas! Thx

Collapse
 
technikhil314 profile image
technikhil314 • Edited

Although this might fit for similar usecases but
react-file-structure.surge.sh/
This is from dan abramov himself. There is no one size fit all solution.

Collapse
 
saeedhemmati profile image
Saeed • Edited

This structure is good enough, but just one issue exists here and that is when we want search index.tsx files and then we get very much results of them and it's painful for me as I have experience about this for finding the specific index file.

I propose fractal structure for react apps and in near feature I will discuss about it in new article.

Good luck