paint-brush
Developing An Easy-to-Use File Structure for an Extensive React Frontend Applicationby@abelozerov
443 reads
443 reads

Developing An Easy-to-Use File Structure for an Extensive React Frontend Application

by Alexey BelozerovSeptember 18th, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

I'd like to share my approach to architecting a quite large front-end application consisting of dozens of pages and hundreds of components, implemented in parallel by a dozen front-end developers, highlighting the folder structure I'm using to streamline the development in the team.
featured image - Developing An Easy-to-Use File Structure for an Extensive React Frontend Application
Alexey Belozerov HackerNoon profile picture

I'd like to share my approach to architecting a quite large front-end application consisting of dozens of pages and hundreds of components, implemented in parallel by a dozen front-end developers, highlighting the folder structure I'm using to streamline the development in the team.

The main technologies used are TS, React, React Router, Tanstack Query, styled components, but the structure is technology agnostic.

I prefer to keep the folder structure as flat as possible to reduce the learning curve for newly added developers

App folders structure:

/elements
/components
/features
/layouts
/pages
...
App.tsx
router.tsx

/elements

Basic building blocks, typically having minimal internal state, usually enhanced basic components from the UI library.


Examples:

/elements
    /Textbox
    /Tooltip
    /MultiSelectCheckmarks

/components

Blocks composed with multiple /elements. Typically, it does not have API access but can have complex internal states or access to global contexts.


Examples:

/components
    /DataGrid
    /List
    /Modal
    /ErrorState

/features

Set of components grouped by domain, typically constructed on top of /components and /elements, with data access, with shared API hooks


Examples:

/features
    /Users
        /UsersList
        /UserEditModal
        Users.api.ts
        Users.api.mocks.ts
        Users.types.ts
    /Projects
        /ProjectsDataGrid
        /ProjectEditModal
        /ProjectHeader
        /ProjectSidebar
        Projects.api.ts
        Projects.api.mocks.ts
        Projects.types.ts

/layouts

Templates shared between multiple pages, say pages in some area of the app shares footer and sidebar.


Examples:

/layouts
    /ProjectLayout
    /AdminLayout
    /StandalonePreviewLayout

/pages

Actual pages connected to routes. Composed with layout and components imported from features and components folders


Examples:

/pages
    /AdminDashboard
    /AdminUsers
    /Project
    /ProjectAddTask

Certain folder like /hooks, /contexts, /utils can be added to top or individual components or feature level on demand

Individual elements/components/pages folder structure:

Individual components follow the agreed file structure to simplify search and maintainability:

/ComponentName
    index.ts
    ComponentName.tsx
    ComponentName.styles.tsx
    ComponentName.types.ts
    ComponentName.tests.tsx
    ComponentName.stories.tsx


Where:

  • index.ts - re-export to shorten imports
  • ComponentName.tsx - component code
  • ComponentName.styles.tsx - styled components
  • ComponentName.types.ts - TS types used more than once, or placed in separate file to avoid circular dependencies
  • ComponentName.test.tsx - unit tests
  • ComponentName.stories.tsx - storybook stories for component


Plus files typically found in /features:

  • FeatureName.api.ts - API hooks used amount the components included into the feature
  • FeatureName.api.mocks.ts - mocks for API call to use in tests and storybook stories
  • FeatureName.types.ts - TS types used amount the components included into the feature


I'm using ComponentName prefix everywhere to ease search in IDE and logs, and have the full context of the file when looking at opened files tabs in IDE.


Certain files can be omitted as I'm putting things inline when if makes sense and extracting out certain styles components and styles when they're used more than once and it makes sense to achieve better code structure

Conclusion

I've found the above folders and file structure quite usable in large enough frontend applications from my almost 15 years of development experience. Glad to hear your feedback in the comments!


Putting the expanded structure example below:

/elements
    /Textbox
        index.ts
        Textbox.tsx
        Textbox.styles.tsx
        Textbox.types.ts
        Textbox.tests.tsx
        Textbox.stories.tsx
/features
    /Users
        /UsersList
            index.ts
            UsersList.tsx
            UsersList.styles.tsx
            UsersList.types.ts
            UsersList.tests.tsx
            UsersList.stories.tsx
        Users.api.ts
        Users.api.mocks.ts
        Users.types.ts
    /Projects
        /ProjectsDataGrid
            index.ts
            ProjectsDataGrid.tsx
            ProjectsDataGrid.styles.tsx
            ProjectsDataGrid.types.ts
            ProjectsDataGrid.tests.tsx
            ProjectsDataGrid.stories.tsx
        Projects.api.ts
        Projects.api.mocks.ts
        Projects.types.ts
/layouts
    /ProjectLayout
        index.ts
        ProjectLayout.tsx
        ProjectLayout.styles.tsx
        ProjectLayout.types.ts
        ProjectLayout.tests.tsx
        ProjectLayout.stories.tsx
/pages
    /Project
        index.ts
        Project.tsx
        Project.styles.tsx
        Project.types.ts
        Project.tests.tsx
        Project.stories.tsx
App.tsx
router.tsx