Organize your React app a little bit better

4 min read

Jan 9, 2026

Hi there! Welcome to my blog, this is Alan.

Today, I am sharing with you an approach that I have been using to structure my React app. This has been working well for me for years. It is simple, but at least the code is organized, and hopefully it gives you another option on your way of exploring a good one for your work.

Let’s get started!

I have been using NextJS, so if you are using other React framework, that works too.

Here is the structure. It is simple enough you even know what each of them will have.

“pages”:

This one acts a path router, so each route will have a component file respectively.

Example:

  • Your web has 3 paths: the root path /, /profile, and /products
  • You will have 3 files respectively for those paths: index.tsx for /, profile.tsx for /profile, and products.tsx for /products

Thanks to the NextJS, they have the built-in routing function work like a charm that we don’t need extra step to make it work. But if you are using react-router-dom, I think you can import these pages into your routing config file.

How about sub-route, like /profile/settings?

Then you just need to create “profile” directory in the “pages” and you will need:

  • index.tsx for /profile
  • settings.tsx for /profile/settings

You may ask, why don’t we just create both profile.tsx and settings.tsx under the “pages” instead?

Well, that works and no problems at all. But the main point of having the sub-dir “profile” is a well-organized structure which reflects the routing. Imaging how easy it is when you want to know which component is for the route /profile/settings, you jump directly to that directory, thinking naturally.

“components”

I put all of components under this one including Button, Modal, Table, Layout, Header, Footer, Sidebar, and even Page Component.

For Page Component, I mean if a page is complex which I have to break down into smaller components and hooks, then I will move it to this “components” , the page component in “pages” only needs to import this one.

For example: /profile page has 3 sections: User Info, Reset Password, and Invitations.

  • I will create components/Profile for that page
  • Then in the pages/profile.tsx, I will import components/Profile and export it.
  • I always want to keep “pages/” simple.
“hooks”

Storing all of global hooks such as useUser, useRoutes, etc…

For hooks that are specifically used for a components but not other, you should create a hooks directory in that component dir to store those hooks.

“stores”

This one is for state management such as Redux, Zustand, or other your favorite one.

I love using Redux + RematchJS + some of great lib such as “immer” which is a great combo, quick setup.

“api”

This one can’t be missed, except your app only has static pages. 😁

Put all of your apis call here, api configuration, api interceptor.

“tanstack useQuery + axios” are my favourite choices. useQuery has many advantage features and axios gives you power to control api configuration, like, intercepting response or request.

“constants”

You shouldn’t use Magic String or repeat string/number again. Assign them to variables and give variables meaningful names.

Not only it helps your team members know what it is, but also when you revisit it and how easy when you change the value, all of places using the variable get updated as well.

“utils”

A place for small helpful functions, such as formatDate(), formatCurrency(), downloadFile(), initGoogleGA(), initSentry()

I don’t put functions that handle specific business logic here. It should only contains common helpful functions that you can bring to and use them in other projects.

“types”

Define objects Types for your app

I always use .d.ts and don’t have to import them where I use, very convenient. I don’t use .d.ts when I want to make a component into a library.

“theme”

UI framework makes my life so much easier and better. My best friend is Chakra UI. It includes all of the essential components, also supports dark/light mode, and responsive at ease.

Sometimes your project may need more, like, “static” for storing icons, fonts, etc… or something else. It depends, but these are the essential ones I think we always need.

If you find this setup fits your need, you can use my package to help generate the source code and save your time.

https://www.npmjs.com/package/@tinychange/new-next

1npx @tinychange/new-next your-project-name

Good luck with your next project!

Thanks for reading!