DEV Community

Cover image for How I structure a React project
Maciek Chmura
Maciek Chmura

Posted on • Edited on • Originally published at maciek.cloud

How I structure a React project

There are many guides on how to structure web apps and React in particular.

  • Move files into folders based on Smart/Dumb components.
  • Organise them by the Header/Main/Footer
  • Or throw everything to Components and combine them in Pages???

I’ve never been fully convinced to use any of these conventions.
And then, about 2 months ago I started a new project. Simple tech stack: React + Express + MySQL.
After a few commits, I had to move the components somewhere.
After a little bit of research, I found something promising.
It's based on 2 resources:

  1. Dan Abramov's official guide
  2. Brad Frost's Atomic Design

Dan gave me freedom and Brad gave me structure 😅

Atomic Design introduces a new, abstract way to think about project structure. Components are building blocks of an app.
Atoms, molecules, organisms, templates, and pages. This concept brings a breath of fresh air to how we can think about structure.
For my purpose, I used the first 3, but I encourage you to read Brad's guide and adapt it to your liking.

I started with a sketch:
sketch

Main idea:
3 folders: Atoms, Molecules, Organisms
If the component has logic/state -> move it to Organisms.
If the component has other components -> move it to Molecules.
Otherwise, the component is an Atom.

I like the organic analogy. It creates a mental and logical box for React components. If needed, I can add more non-organic folders for Utils, Routes, API, etc.
A Button will be in Atoms.
A Card will be in Molecules.
Component with Hooks will be in Organisms.

src/
  Atoms/
    Button
    ProjectName
    ...
  Molecules/
    ControlBar
    DaysList
    ...
  Organisms/
    User
    CreateUser
    ...
  Utils
    formatMonthData.js
Enter fullscreen mode Exit fullscreen mode

For now, this works with no flaws with my project. I will reevaluate this concept when my project grows.

Top comments (16)

Collapse
 
thekashey profile image
Anton Korzunov • Edited

I hate this approach. Oh, how I hate this approach.

Let's say - you need a Button.

  • While you are developing it - it could be clear for you what it is. Probably it is an Atom.
  • But then you are refactor it, extracting some pieces, and BAM! it shall be a Molecule.
  • Then you will add some state to it, to track visual state in a fancy way and BAM! it shall be an organism.
  • Then you reactor it to keep all the "state" in a CSS - you can do it for a button.
  • And what then? Shall it be atom again? It quaks like an Atom, it's walks like an Atom - IT'S AN ATOM!

Even worse scenario - you have keep this component discoverable. You have to know there to look for it.

Separation shall not be done by how something is made - it's an implementation detail. Separation shall be done by a responsibility you can reason about - screen, page, component, internal component stuff which shall not be ever used outside.

Smart/Dumb component separation is also quite dumb. It's a right separation, but you might have both components if not in one file, then in one directory.

Separation should be made in a way you never would be forced to rename or move your component after refactoring, and it would be always easy to find it. And use. And test.

Collapse
 
maciekchmura profile image
Maciek Chmura

Thank you for this strong opinion :)
It is always good to know what are the drawbacks of a given approach.

This idea is a living process.
Thanks to your feedback, maybe we will optimize it, or discover even something better.

Collapse
 
jsardev profile image
Jakub Sarnowski • Edited

I've tried this approach and I didn't like it. Mostly because I found it problematic to find the components I was looking for.

For example: imagine a Button with IconButton and ProgressButton variants. In this case, the Button goes to Atoms, IconButton to Molecules (as it contains other components) and the ProgressButton to organisms (as it tracks some progress in the state). Now, it wasn't always clear to me where should I look for the specific component. And this was an even bigger problem for someone who just joined the project. It's a lot easier to have related components next to each other.

(btw. I know that the ProgressButton could just accept progress and be a Molecule, treat it just as an example!)

This wasn't a problem when the project was small, but as soon as it became bigger, it was a lot easier to just put all components into one folder, or just structure them by feature.

But that's just my opinion :D It "feels right" for me - quoting Dan Abramov's words - but everyone feels different :)

Collapse
 
maciekchmura profile image
Maciek Chmura

Thanks for this insight ;D
I wonder if I will have the same feeling when my project grows.

Collapse
 
kayis profile image
K

Cool idea. I use screens and components, but the components directory gets rather unwieldy xD

Collapse
 
glyphcat profile image
GlyphCat

Same here, tho I have a folder called "modules" which I believe is similar to the Utils mentioned in the main thread.

You could try dividing your components folder (instead of src) using the organic analogy, perhaps that would help?

Collapse
 
kayis profile image
K • Edited

I got

  • modules
    • components
    • screens
    • utils

The components directory is the biggest, but I'm looking into react-native-elements right now, so maybe this will remove the need for most of my small/dumb components.

Collapse
 
adameier profile image
adam meier • Edited

I like the idea, but personally I dont think the logic|state => Organism rule should be so strict. In my experience there would be many times in which a component such as a form uses stateful logic, but doesn't contain "application specific" logic (I hope that term makes sense), which would make it be more suited as a Molecule rather than an Organism.

Collapse
 
javaguirre profile image
Javier Aguirre

I like this separation, it’s very interesting. The naming is also intuitive.

I use Redux on my projects, so for me Organisms would be connected components.

For Atoms could be PureComponents, that would be a good approach, simplifying its lifecycle.

Collapse
 
ravitej5226 profile image
Raghav

Cool idea. The pages and other components coexist in Organisms. Have you had any difficulty with the coexistence? I tried multiple ways to structure so far with no luck.
Right now, I use pages, containers, components to structure my project.

Collapse
 
maciekchmura profile image
Maciek Chmura

If you like you can add Pages (if they combine multiple Organism). We need to listen to Dan and do what works for us :)
I would suggest you to test it and see how you like it.

Collapse
 
felixdorn profile image
Félix Dorn

if e.g a Card use a CardHeader, the CardHeader should be in atoms in a Card folder or in the molecules folder

Collapse
 
maciekchmura profile image
Maciek Chmura

I don' like long import strings, so in my case, I want to have a flat folder structure.
I prefer to not do multiple nestings. So I have only one Atom folder, one Molecules ,etc.
I think that with something like this:

src/
  Molecules/
    Card/
      Atoms/                   << to much nesting for me
          CardHeader

it gets harder to navigate the project.
But please, test it and see if it works for you :)

Collapse
 
raisaugat profile image
Saugat Rai

This is really cool.
I aways get confused on how to manage my files on project. Moving files doesn't seems right unless you have a better folder structure.

Collapse
 
seanmclem profile image
Seanmclem

You use an example of a Form as a molecule, but say that once they have logic they are an organism. Wouldn't a form have logic?

Collapse
 
maciekchmura profile image
Maciek Chmura

🤔
Valid point.
I had in mind more of a business logic component, but a form should also fall into Organisms.
I'm editing it to 'Card'
thx :)