Blog

Organizing React Native Codebase

February 9, 2023 7 min read

Best practices for organizing and structuring large React Native applications. Learn about folder structure, component organization, and maintainable code patterns.

Organizing React Native Codebase
React NativeArchitectureCode OrganizationBest Practices

Organizing Your React Native Codebase

A Guide to Creating a Scalable and Maintainable Codebase

In a React Native application, organizing the codebase is crucial for maintainability and scalability. The way you structure your files and folders can greatly impact the ease with which you can work with the codebase in the future.

This article will explore the feature-based folder structure for a React Native application and the purpose of each folder.

The src Folder

The src folder is the root directory for all of your application's source code. Within this folder, you will find several other subfolders that each serve a specific purpose.

Types

The types folder is where you will define global types for your application. This includes module types, interface definitions, and any other custom types you need to use throughout the application.

Having a central location for all of your types makes it easier to manage and maintain them as your application grows. Additionally, it ensures that your types are consistently used across all features, reducing the risk of type-related bugs and making it easier to catch them when they do occur.

Lib

The lib folder is where you can keep any application-specific files that are used globally throughout the app. This can include the axios instance for making API calls, error handling services, constants, setting up query client in react-query etc.

Having these files in a centralized location makes it easier to maintain them and ensures that they are consistent across the entire application.

Components

The components folder is where you will keep all of your reusable components. These components should be isolated and not specific to any particular feature or domain. Examples of these types of components include headers, buttons, and list items.

Keeping these components separate from your feature-specific components makes it easier to manage and reuse them throughout your application and reduces the amount of duplication in your code.

Hooks

The hooks folder is where you will keep any custom hooks that are used throughout your application. A hook is a special type of function in React that allows you to reuse stateful logic across your components.

Having all of your **reusable/used in multiple places **custom hooks in a centralized location makes it easier to manage and maintain them, as well as reducing the risk of code duplication and making it easier to share hooks across different parts of your application.

Localization

The localization folder is where you will keep all of the files related to internationalization in your application. This includes language files, string constants, and any other resources needed to support multiple languages in your application.

Having these files in a centralized location, it makes it easier to manage and maintain them, as well as reducing the risk of code duplication and making it easier to support multiple languages in your application.

Navigation

The navigation folder is where you will keep all of the code related to navigation in your application. This includes the stacks, types, routes, and any other components or functions needed to support navigation.

By having all of your navigation code in a centralized location, it makes it easier to manage and maintain it, as well as reducing the risk of code duplication and making it easier to share navigation functionality across different parts of your application.

Services

The services folder is where you will keep all of the code related to the underlying infrastructure of your application. This includes code for working with push notifications, error monitoring, and any other services that are used to provide the underlying functionality of your application.

Theme

The theme folder is where you should store your app's styling, for example dark/light theme. Keeping your styling and theme files in one place makes it easier to manage and update your app's look and feel as needed.

Utils

Utility functions can be an important part of your React Native application, as they provide a way to reuse code that can be used in multiple parts of your application. The utils folder in your application is a great place to store utility functions that are used throughout your application. By centralizing these functions in one location, you can ensure that they are easy to find and use in other parts of your code. For example: react-native layout related utility functions.

Features

When it comes to building complex applications, it’s essential to have a clear and concise folder structure that encapsulates all of the code in one place. Having a features folder helps to achieve this as it separates all the different features of the application into distinct categories. This allows developers to quickly find and make changes to a specific feature without affecting other parts of the application.

Moreover, as the application grows and more features are added, the folder structure remains organized, making it easier for new developers to jump in and understand how the application works. The clear separation of concerns also helps to reduce the risk of bugs and improves the overall performance of the application.

Here’s what an auth folder could look like:

    src/
    ├── ...
    └── features/
        ├── auth/
        |   ├── api/
        |   ├── helpers/
        |   ├── hooks/
        |   ├── screens/
        |   ├── services/
        |   └── store/
        └── ... (other features)

The importance of the features folder lies in its ability to help divide the codebase into smaller, more manageable parts. Each feature has its own subfolders, such as api, helpers(or utils), hooks, screens, services, and store, that are specific to that feature. This makes it easier to understand how each feature works, as well as how they interact with one another.

The api folder contains all the API-related code specific to authentication. This makes it easier to manage the API calls and keep them organized.

The helpers folder contains helper methods or utility functions that are specific to the authentication feature. They can be used exclusively within the authentication feature and do not need to be shared with other parts of the application.

The hooks folder contains hooks that are related specifically to authentication. Since React is heavily dependent on hooks, this makes it easier to manage the hooks and keep them organized.

The screens folder contains all the screens for the authentication feature. This includes the login screen, sign-up screen, and forgotten password screen, among others.

The services folder contains services that are specific to the authentication feature. For example, you might have an authentication service that is responsible for handling user logins and sign-ups.

Finally, the store folder contains the state management code specific to the authentication feature. This can be a Redux store, a Zustand store, or any other state management library you prefer.

By breaking down the application into smaller, organized parts, it becomes much easier to manage the code and make changes to it as needed. It also helps keep the code clean and readable, making it easier for other developers to understand and work with the code.

Sample structure of auth feature folder

    src/
    └── features/
        └── auth/
            ├── api/
            |   ├── login.ts
            |   ├── signup.ts
            |   └── refresh-token.ts
            ├── helpers/
            |   ├── validateToken.ts
            |   └── dataTransformer.ts
            ├── screens/
            |   ├── Login.tsx
            |   └── Signup.tsx
            ├── services/
            |   └── validation.ts
            └── store/
                └── auth.ts

The auth folder is the subfolder dedicated to the authentication feature of your application. The files in this folder handle everything related to authentication and authorization, from the APIs for login and signup to the UI screens for the user to interact with.

The api folder holds the APIs for the authentication feature, such as the login.ts and signup.ts files, which handle the requests and responses for the user's login and signup requests. The refresh-token.ts file handles the refresh of the token.

The helpers folder holds helper functions that utilize in the authentication process. For example, the validateToken.ts file is used to validate the token, and the dataTransformer.ts file transforms data to and from the authentication APIs.

The screens folder holds the UI components that the user interacts with. For example, the Login.tsx and Signup.tsx files contain the UI components for the user to log in and sign up, respectively.

The hooks folder holds custom hooks related to authentication. For example, the useLoginAction.ts and useSignupForm.ts files contain hooks that help manage the state and actions related to the login and signup forms, respectively.

The services folder holds services related to authentication, such as the validation.ts file, which holds functions to validate the user's input.

The store folder holds the state management related to authentication. The auth.ts file holds the state and actions related to authentication, using a state management library like Zustand, Redux, or another one.

CAVEAT

It is important to note that the naming conventions of the folders and files can vary from project to project and from developer to developer. The structure and organization of the folders are what’s important, rather than the exact names used for each folder. For example, the utils folder in the root of the app could also be named helpers, utilities, or instead of screens it could also named as pages or something else that makes sense for the specific project. The goal is to have a clear and consistent structure that helps developers understand the organization of the code and makes it easier to maintain and scale the application.

Type-based folder structure vs Feature-based folder structure

Another widely adopted method for organizing a project’s codebase is the type-based folder structure, which has its own set of pros and cons. In the following section, we will compare and contrast these two folder structures visually.

Comparison

    Feature-based folder structure:

    src/
    └── features/
        ├── auth/
        |   ├── api/
        |   │     ├── register.tsx
        |   │     ├── login.tsx
        |   │     ├── types.tsx
        |   │     └── helpers.tsx
        |   ├── helpers/
        |   ├── hooks/
        |   └── screens/
        |   │     ├── LoginScreen.tsx
        |   │     ├── SignupScreen.tsx
        |   │     ├── WelcomeScreen.tsx
        |   │     └── HomeScreen.tsx
        |   ├── services/
        |   └── store/
        ├── todo/
        |   └── screens/
        |   │    └── TodoListScreen.tsx
        |   ├── services/
        |   └── store/
        └── ... (other features)

    Type-based folder structure:

    src/
    ├── screens/
    |   ├── LoginScreen.tsx
    |   ├── SignupScreen.tsx
    |   ├── TodoListScreen.tsx
    |   ├── WelcomeScreen.tsx
    |   └── HomeScreen.tsx
    ├── api/
    |   └── auth/
    |       ├── register.ts
    |       ├── login.ts
    |       ├── types.ts
    |       └── helpers.ts

As can be seen above, in the type-based folder structure, the screens are separated from the API calls and helpers, which can make it harder to understand the codebase. Notice how we might end up placing unrelated screens such as LoginScreen.tsx and TodoListScreen.tsx under the same folder in the type-based folder structure. Additionally, it can also make it harder to maintain the code as the related code is not grouped together in one place. While in the feature-based folder structure, all of the code related to authentication, including the screens, API calls, helpers, and services, are grouped together in one auth folder. This makes it easier to understand the codebase, as all of the related code is located in one place. This approach allows for better encapsulation of code and makes the project scalable and flexible for future changes.

The latest picture with a feature-based folder structure

Below is how it would look in the end with the feature-based folder structure with dummy files:

    Feature-based folder structure:

    src/
    ├── components/
    │   ├── Button.tsx
    │   └── Header.tsx
    ├── hooks/
    │   └── useHeader.ts
    ├── localization/
    │   ├── languages.ts
    │   └── locales.ts
    ├── lib/
    │   ├── axios-instance.ts
    │   └── constants.ts
    ├── navigation/
    │   ├── root-navigator.tsx
    │   └── auth-stack.tsx
    ├── services/
    │   ├── notification.ts
    │   └── logging.ts
    ├── theme/
    │   └── index.ts
    ├── types/
    │   ├── env.d.ts
    │   └── react-augment.d.ts
    ├── utils/
    │   └── layout.ts
    └── features/
        ├── auth/
        │   ├── api/
        │   │   ├── login.ts
        │   │   ├── signup.ts
        │   │   └── refresh-token.ts
        │   ├── helpers/
        │   │   ├── validateToken.ts
        │   │   └── dataTransformer.ts
        │   ├── hooks/
        │   │   ├── useLoginAction.ts
        │   │   └── useSignupForm.ts
        │   ├── screens/
        │   │   ├── Login.tsx
        │   │   └── Signup.tsx
        │   ├── services/
        │   │   └── validation.ts
        │   └── store/
        │       └── auth.ts (zustand, redux, jotai etc.)
        └── ... (other features)

The files that were added to the various folders above (e.g. button.tsx, header.tsx in the components folder, useHeader.ts in the hooks folder, etc.) are meant to serve as examples and should not be taken as 100% accurate. The purpose of including these files is to provide a visual representation of the folder structure and help to better understand the organization of the codebase. The actual implementation may vary based on the specific requirements of the project. The focus of this article is on the feature-based folder structure and how it can help to build a scalable and organized codebase, rather than on the specific details of individual files.


Conclusion

In my opinion, the feature-based folder structure is a useful approach for organizing React/React Native projects. By breaking down the code into separate features, I find it easier to maintain, understand, and develop the application. This structure allows for better encapsulation of code, making the project scalable and flexible for future changes. Of course, this is not a one-size-fits-all solution, and the exact structure may vary depending on the size and complexity of the project. However, the key idea is to keep a clear separation between different features and their respective components, services, and data. In my experience, this structure has helped me build and maintain well-organized projects that are capable of handling growth and change over time. I wanted to share this approach with others who may find it useful as well.

Published on

This article is also published on: