As you know React is not an opinionated library. What that means is that there is no clearly defined way of doing things, for instance, React doesn't force you to structure your projects in a certain way. All that is left for you the developer.
Here we are going to be using NextJS, which is a framework built on top of React. NextJS helps us by optimizing our app through code-splitting, image optimization, static site generation, server-side rendering, etc. In this article, we are ignoring all this awesomeness as it is not the focus of the article. I recommend looking at NextJs docs if you are new to it.
Below is a high-level folder structure of our app.
📦src
┣ 📂charts
┃ ┣ 📜index.js
┃ ┗ 📜sunburst.js
┣ 📂components
┃ ┣ 📂breadcrumb
┃ ┃ ┣ 📂styles
┃ ┃ ┃ ┗ 📜breadcrumb.js
┃ ┃ ┗ 📜index.js
┃ ┗ 📜index.js
┣ 📂containers
┃ ┣ 📜index.js
┃ ┗ 📜navbar.js
┣ 📂fixtures
┃ ┗ 📜data.json
┣ 📂lib
┃ ┗ 📜gtag.js
┣ 📂pages
┣ 📂public
┃ ┣ 📂fonts
┃ ┃ ┗ 📂Arial
┃ ┣ 📂icons
┃ ┣ 📂images
┃ ┃ ┣ 📂svg
┃ ┣ 📂videos
┃ ┣ 📜manifest.json
┃ ┣ 📜sitemap.xml
┃ ┗ 📜sw.js
┣ 📂scripts
┃ ┗ 📜generate-sitemap.js
┣ 📂styles
┣ 📂utils
┣ 📜.env
┗ 📜next.config.js
Yes I know, this looks a bit complex. Let's demystify it by looking at each folder separately.
Charts
Usually, my applications have some charts to visualize data. All my charts will be located here and exported from an index.js
file that acts as a barrel.
Components
This is probably the most interesting folder because that's where you will spend most of your time in. For each component in my components, I create a separate folder for it, and in that folder I create an index.js
file to export the component and a separate folder for the component styles. There is also an index.js
file in the components folder that exports all the components. If you then want to import say a <Button />
component you will do it like so import { Button } from 'components'
Containers
This folder is also important. Components acts as atoms and if we combine those atoms we form elements. For example if we combine links, buttons and grids components(atoms) we can create a navbar container(element). This makes it easy to compose to UIs. These containers are imported in pages to form the complete webpages.
Fixtures
This folder contains some static data like a list of all links.
Lib
Files in this directory acts as an interface between our application and external libraries like google analytics.
Public
This folder host the static files like images, fonts, videos, sitemaps, service workers, etc.
Scripts
This folder contains some scripts that I usually run at build time like generation of sitemaps.
Styles
Global styles are stored in this directory.
Utils
Functions that I want to be shared across the whole application are stored in this directory.
I hope this article helped you, let me know if you have another folder structure that you want me to look at. I will be happy to try it out.
Top comments (17)
It’s a lot of index.js. Do you ever find that’s inconvenient in the code editor tabs? My team did and no longer use index.js files.
This is called Barel export and it helps with tree shaking and bundle resolution. In large project it helps to bundle it faster. I do recommend to use barel exports.
Regards!
I also like the convenience of importing components from
components
instead ofcomponents/button
that's why I sometimes find myself using these index filesFor my projects instead of index.js I call them the name of the folder example header/header.js it is more clean and you'll not get confused
how is it clean ? header/header its like repeatition. is it gonna be
wow
If you use default export it would be, you don't need to explicitly say import Header, in my prospective it is not needed
Yes you are repeating the name, you are right, but you solve the problem of having multiple index.js.
As example you have main.js file that is importing all the components:
Now if in my editor I have all this files open I see 4 index.js files, if I call the in this other way:
In my tabs I see header, footer, leftbar etc... I have used it and I found myself great with it, but as always it is a matter of preference, there is no you must do this or that, you are free to choose any style you like
Organising code by feature is the way forward. I shudder whenever I see /components...
Do you have any examples of organising code by feature? I'm curious as to how that goes as I very much have a similar approach to this article at the moment, but I'm definitely open to trying different methods.
Ignore me, I should learn to google things more haha. I'm guessing you mean something along the lines of this right? reactjs.org/docs/faq-structure.htm...
That's interesting, I'll have to try that approach in my next project. It can be super frustrating sifting through a huge
components
directory so having onecommon
directory for anything shared and everything else being at a page or feature level could look more organised.Yh this is it exaxtly. I haven't done a lot of next.js so I'm not sure how this works with pages, but essentially you have a folder for a feature, say like "user" then within that you can have your UserProfile component, your EditProfile component and whatever else all conveniently co-located. I also a proponent of having your tests next to their subject files so they're easy to update.
If these folders grow too large you can break them down into sub features.
Seems to be maintainable, but how do you deal with shared and small components like buttons?
As Robin has alluded to you can have a common folder. I in fact have a fairly large common folder, broken down into sub-features - e.g.
common/buttons
. I also don't like theindex.js
approach as someone else has mentioned so I would havecommon/buttons/SaveButton.js
,common/buttons/CancelButton.js
etc. Then oneindex.js file
in buttons to export these.For common you can even then add a webpack alias so you can import these from anywhere without lots of
../../
, e.g.import { SaveButton } from "@common/buttons";
index.js is bad. Try a project without will be much cleaner.
do you have any article that support your opinion as to why using index.js is bad ?
Index.js is not meant to be used like that, first of all the guy who created node was at first unsure to make index behave like in the browser, this is what I read somewhere, also only because React is a component framework it doesn't mean every component needs to be an index, there is no benefit at all it messes with your DX in the editor the project gets more complex and it is simple not meant to be used like that.
Yes makes sense, you can use just one index file to export all components from the components directory.
What I do is represent all the pages I have in the pages directory with a folder inside components, so if I have a News, Contact, About inside my pages dir. I have inside /components for all them a folder called also /News, /Contact, /About and inside them there are just react components who belong to them, very important at this point is to never create folders at this level just drop the components inside the folder of the page, if you have components used by multiple pages or subcomponents for this I have a folder shared /components/shared. To keep everything clean as possible I recommend Recoil.js for state or Jotai. I work on this structure for over an year now and I had never a cleaner project everything just makes sense when you look at it.