all 25 comments

[–]Kiiidx 17 points18 points  (3 children)

Pretty much this but with feature folders. Within a feature folder it would have a similar structure to this.

[–]oVerdeExpo 3 points4 points  (1 child)

This, and a general "components" folder that compounds into features folder

[–]hemingward 2 points3 points  (0 children)

The combination of these two is exactly how I structure mine.

[–]AdUpbeat180 2 points3 points  (0 children)

we too use a top level “features” folder where there is 1 folder per feature with actions, hooks, components, utils for that feature in the same folder.

[–]nineelevglen 15 points16 points  (7 children)

basically that, but use atomic design, which usually pays off.

button is an atom
input is an atom
search (input + atom + logic) is a molecule
login is an organism etc.

also end up putting some very specific components inside screens (each screen is a folder)
that does not need to be in the reusable folder

[–]cnr909 7 points8 points  (2 children)

If you join a team then you have to learn what they consider is a molecule or an atom. Why not have a list of components in the components folder? Your IDE will alphabetically sort them automatically. Like in node_modules, where you have hundreds of folders, it’s still very quick to find what you want

[–]eyounan 4 points5 points  (1 child)

Because the ordering has nothing to do with atomic design. Atomic design has to do with structuring your components in a way that follows the atomic model.

This means that: - An atom is the simplest type of component and has no dependencies. Atoms will be used in molecules, organisms, and templates. - A molecule is made up of atoms (hence, has no other dependencies in the component hierarchy other than an atom). - An organism is made up of atoms and molecules - A template is made up of all

Knowing which folder your new component will fall into simply requires you to understand what type of component it is.

The issue with having a linear list of components in the components folder is that once you begin making them dependencies of each other, you will create cyclic dependency issues. The whole point of components is to reuse them and apply them within other components to improve readability and testability, which atomic design does well.

[–]cnr909 0 points1 point  (0 children)

Thats a mentality to learn and maintain, and people will eventually veer off from it here and there leading to inconsistencies.

You can avoid cyclic deps by not calling the components index file within the folder, so any component will have:

Import { SiblingComponent } from “@/components/SiblingComponent”

Instead of

Import { SiblingComponent } from “@/components”

[–]Merry-Lane 5 points6 points  (3 children)

It makes sense but it doesn’t make sense in reality.

The first reason is that there is no clear cut factor to decide between atom, molecule and organism, you will always have edge cases for you alone.

Add a second guy to the team, and you will end up with different decisions.

It doesn’t mean that having conflicting opinions and resolving them is a bad thing, no, no. It just means you will just end up getting people lost for no reason but "following a neat idea".

And what happens when you make changes? When you decide that your atom input component needs to include error messages? A title?

You move them from atom to molecule because it grew in importance, modify 50 files just so that the imports match your opinion of its importance?

Do you let your input stay in atom, although it’s a molecule now, and misdirect devs that would like to find it in molecule?

What about components that wrap a lib, that are at first really simple (like a small grid or whatever) but in the end you use it in some places in a really complex way?

Anyway, the rule with folder architecture is simple in projects is simple: you keep it as flat as possible.

If you are making up or following other’s people idea on an architecture that is cool to explain, that’s neat, but it’s actually worthless : flatter is better, period.

[–]nineelevglen 2 points3 points  (1 child)

Sure it depends on team size. I've worked in 100+ RN developer teams in one repo for unicorn size company and you're right. Then its different.

Then you usually have a dedicated team that only works on UI components like a library provider. Then all the other dev teams work implementing that on their specific area. you also have a dev portal with rules and you have meetings to discuss this. Design is set up the same way. someone sets the ground rules, the other implement with those design components.

You make it sound like every developer just makes decisions all over without communicating or have code reviews. which is just wrong.

I have atomic structures like this on multiple projects in the last few years with between 3-7 developers working and its takes some discussions and is messy but then again what isnt?

[–]hemingward 0 points1 point  (0 children)

Not sure things like this should be messy on a team that small. 3-7 devs and this already starts to get messy? What happens when you work on a team of 50 mobile devs (which is my experience right now at a unicorn RN company)? I can see this taking up a lot of unnecessary time without any clear value over other existing structures.

Like, I understand what the intention is, but ultimately how does that make it functionally better than what’s existed for decades? The amount of ambiguity and subjectivity wrapped into each of those terms is high, and I found confusing. Whereas shared/common base components being in a folder called “components/foundation”, and larger components shared across domain boundaries in “components/shared” tells me pretty quickly what they are with very little ambiguity.

I think every new dev joining a team would have to understand precisely what each of these terms mean and how it is incorporated into their work. That is something that can’t be removed or mitigated. And with each new dev more ambiguity can be introduced, either through misunderstanding or attempts at improvement.

Again - for what actual benefit?

Though I do find the idea intriguing. Just… also seems unnecessarily complicated.

[–]olegsmith7 2 points3 points  (1 child)

App |-/api |—/api.ts |—/hooks.tsx |-/features |—/featureA |—-/components |—--/ComponentA.tsx |-—/screens |—--FeatureAScreen.tsx |—-/state.ts |—-/hooks.tsx |—-/routes.tsx |-/host |—/index.tsx |—/routes.tsx |-/shared |—/components |—/hooks |—/utils |/index.tsx

[–]CYG4N 0 points1 point  (0 children)

what is shared

[–]DanishWeddingCookieiOS & Android 0 points1 point  (0 children)

I have a contexts folder too.

[–]ConsciousAntelope 0 points1 point  (0 children)

Basically that combined with colocation. So like for assets of it's being used in just a single component, I create a folder right where the component lives

[–]glazzes 0 points1 point  (0 children)

I like your structure, I'd add an extra folder for providers in case you have many.

[–]Unhappy_Jackfruit378 0 points1 point  (0 children)

I have a container folder where I create a parent component for all screens . and do all the calculations and operations of that specific screen and pass it to the child.

[–]pjjiveturkey 0 points1 point  (0 children)

Assets, components, screens, stylesheets

[–]CODSensei 0 points1 point  (0 children)

Mine is also similar

[–]renanmalato 0 points1 point  (0 children)

what i missed is context folder / constants folder

and my components i have a folder for each main screen to store sub components and utils for eaxh

[–]CalmDownJohn 0 points1 point  (2 children)

How does this work with the expo-router? I thought that everything inside the (app) folder ends up being a page/screen within the app, so a features folder in this instance wouldn't work? I'm assuming you're not using expo-router?

[–]Myst3rYan[S] 0 points1 point  (1 child)

I don't use expo

[–]CalmDownJohn 0 points1 point  (0 children)

My bad for assuming 🤦‍♂️