DEV Community

Richard Oliver Bray
Richard Oliver Bray

Posted on

You've been structuring files in projects wrong

Originally posted here https://medium.com/octopus-labs-london/how-to-structure-files-in-large-react-projects-48ee3dc424ed

Okay I admit, I've got your attention with a somewhat catchy title but hear me out.

When you tend to have large React, Svelte, Vue, any frontend framework (or library) project, it's easy to put all the components in a components folder, containers in the containers folder and so on. Well I have a different approach for really large projects. Something that looks a bit like this

public/
package.json
index.ts
src/
│
├── components/
│   ├── Button/
│   │   ├── Button.tsx
│   │   ├── Button.tests.tsx
│   │   └── Button.css
│   ├── Dropdown/
│   ├── Toaster/
│   ├── Header/
│   └── Footer/
│ 
├── layouts/
│   └── StoreLayout/
│       ├── components/
│       │   ├── SearchDropdown/
│       └── StoreLayout.tsx
│ 
└── pages/
    ├── StoreProductPage/
    │   ├── components/
    │   │   ├── Carousel/
    │   │   └── ProductCard/
    │   └── StoreProductPage.tsx
    │
    └── StoreCheckoutPage/
        ├── components/
        │   └── ProductCheckoutCard/
        └── StoreCheckoutPage.tsx
Enter fullscreen mode Exit fullscreen mode

This way it's easy to remove pages without other parts of the site. All the general components go in the components folder. But Page specific components go in a sub-folder.

Not quite convinced?

Check out my video explanation on YouTube.

Let's talk

It would be good to hear your thoughts on this approach, if you like or dislike it, and if you have any ideas for improvements. You can find me on the socials, or you can just write a comment below and I promise I'll respond 🙏

Top comments (10)

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

Every component is meant to be on a page or more, or even inside another component or more (think of button component as example).

Then, if you put some components after pages, what will happen is that anytime you need to reuse one of those components in a different place you'll need to refactor for no other reason than an inefficient project structure.

Components are components, layouts are layouts and pages are pages. Mixing them on opinionated or situational shape is usually bad (unnecessary refactors during project further developments). There's why I'll keep adding every single component below components.

Collapse
 
richardbray profile image
Richard Oliver Bray

I think this depends on how you structure your project. If you structure it based on pages which is what I have done then yes, there will be components that are shared between pages and this could go in a components directory. But there will be many components that are only used on one page. In this scenario I would suggest on having a components folder in that page folder so that if you ever had to delete that page, all the components specific to that page go as well.

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

Running a tool (JSLint or any other) to spot "unused" components (a.k.a. functions) is more reliable in such situations, and setting a components folder in each "view/page" still has the issue of having to refactor whenever you need a component in a different view.

Re-imagine things is always good, but the requirement to be successful while doing so is to understand why things are the way they are. If everyone is having a single "components" folder is not by personal preference but for a project maintainability benefit, and because the nature of the components is precisely to be reusable... using a component just once is just a temporal coincidence, and is better to be ready for when that coincidence doesn't happen to exist anymore.

Collapse
 
theaccordance profile image
Joe Mainwaring

If I were to use a title as bold as you have, I would have accompanied it by introducing a very radical opinion in regards to a new file structure; I don't consider this to be radical.

I'm not a fan of this style personally, I prefer a flatter hierarchy and having a nested components section within layouts and pages subfolders sounds like more maintenance than benefit. What happens when I realize StoreProductPage/components/ProductCard is needed for the StoreCheckoutPage page?

the tl;dr here is that it doesn't matter how you lay out your projects, so long as you/your team understand it.

Collapse
 
richardbray profile image
Richard Oliver Bray

Yeah I agree with your last point. This file structure is something I've found very useful particularly for large projects. Maybe for much smaller projects the flat hierarchy works, but imo it falls apart when you're chopping and changing a lot for med to larger projects.

Collapse
 
theaccordance profile image
Joe Mainwaring • Edited

We’ll have to agree to disagree as far as limitations for a flatter hierarchy, I build enterprise SaaS and there aren’t many projects that have a larger scope than I do - unless of course you’re building the UI for GCP or AWS

Thread Thread
 
richardbray profile image
Richard Oliver Bray

Fairplay. I think whatever works for you and your team is good. I've worked on an app with a flat structure where we had to delete a huge chunk of it. We mostly left components folder as is because we weren't sure where the components were being used so the codebase has a bunch of components that potentially don't need to exists.

We could have done a project wide search and looked through the imports to see what was being used where but in hindsight, it would have been easier to delete pages if we had more of a complex file structure like the one I proposed above.

If you look at frameworks like Nextjs and Svelte, they are moving to folder based routing instead of file based routing so that the a folder for a specific page can contain the pages, styles, tests and even components that are only used for that page.

Collapse
 
derlin profile image
Lucy Linder

I have a similar approach for spring boot or quarkus projects (Java).

When I learnt it at school and through tutorials, I always saw the type driven approach, packages like database, controllers, views. But after experimenting a bit, I found component/functionality driven approach to be much more suitable: the package (folder) should group everything related to a given functionality. It is clearer, cleaner, and easier to understand without looking all over the place.

The only thing here is the need for meaningful and consistent suffixes a cross packages/folders: FooDb, FooDao, FooController / BarDb, etc.

My point is, this may apply to every language, and I completely agree with you!

Collapse
 
jesusantguerrero profile image
Jesus Guerrero

Too much nested and duplicated responsibility to my like.

I found very intuitive the atomic Design approach to organize general components.

And a flat structure easier explore and maintain, but it's a subjective topic I guess.

Collapse
 
richardbray profile image
Richard Oliver Bray

Yeah it's a good point, everyone is different. In my opinion, the approach I've shared above works best for medium to large project that have upwards of 50 components. If say 10 of those components only belong to the settings page and for some reason you have to delete the settings page, say it's moving into its own repo. It's much easier to do that with the file structure that I've proposed than using a flat structure.