Skip to content

Instantly share code, notes, and snippets.

@ferrannp
Last active May 6, 2021 00:47
Show Gist options
  • Save ferrannp/eca96276c813612a305e59d70cdb12c2 to your computer and use it in GitHub Desktop.
Save ferrannp/eca96276c813612a305e59d70cdb12c2 to your computer and use it in GitHub Desktop.

React Native Folder Structure

Motivations

  • Sharing what has worked for me in different React Native projects
  • Reusing screens in different parts of your app
  • Easy to work separately in a feature
  • Add an extra level (nested folder) only when necessary
  • Don't overuse index.js for everything

Proposed structure

Screens or Scenes concept

src
└── screens
    ├── Home
    │   ├── RowPanel.js // Component used only in this screen
    │   ├── HomeScreen.js  
    │   └── index.js // Just to export HomeScreen.js
    ├── Exercises
    │   ├── ExerciseList.js
    │   ├── ExerciseScreen.js
    │   └── index.js
    └── Settings
    │   ├── SettingsScreen.js
    │   └── index.js
    └── index.js

Imagine that in the future you add another screen called Calendar, from there you can click a day an access Exercises screen for that day. I find this structure clearer than nesting screens because you never know when you're gonna show the same screen through your app in the future (maybe even reuse the same screen in another app).

Navigation concept

It all depends on your app structure. Let's say I use the Bottom Navigation pattern and react-navigation here. For the structure above, the bar includes Home and Settings. Then I would write:

src
├── screens
│   ├── Home
│   │   ...
│   ├── Exercises
│   │   ...
│   ├── Settings
│   │   ...
│   ├── HomeNavigator.js // Includes routes for HomeScreen, ExerciseScreen...
│   ├── SettingsNavigator.js
│   └── index.js
├── ManNavigator.js // BottomNavigation
└── index.js

Shared modules

One is clear: components used across different screens (like a Button.js). Other modules I like to have as shared modules are those which are not strictly tied to my screens. For example, database or redux. I like to encapsulate everything related to things like the chosen database solution, the API... So if I want to change this completely (and I keep the same API), I will probably not need to change anything inside screens or components.

If you want to use Redux, for example as a caching system, I really encourage you to use the ducks pattern for your folder structure inside redux.

src
├── components
├── database
│   ├── schemas
│   ├── api
│   ├── database.js
│   └── index.js
├── redux
├── screens
├── ManNavigator.js
├── App.js
└── index.js

Tests

I am strictly against of having a src directory and a separated test directory with the same structure. I embrace Jest concept of having your tests file next to your src files using __tests__.

src
└── components
   ├── __tests__
   │  ├── Category.test.js
   │  └── HeaderButton.test.js
   ├── Category.js
   └── HeaderButton.js

Encapsulate when necessary

This is fine:

├── Exercises
    ├── ExerciseList.js
    ├── ExerciseScreen.js
    ├── SomeOtherComponent.js
    └── index.js

But if for example, everything related to ExerciseList.js starts to grow, I like to encapsulate it like:

├── Exercises
    ├── ExerciseList
    │   ├── ExerciseHeader.js
    │   ├── ExerciseItem.js
    │   ├── ExerciseButtons.js
    │   ├── ExerciseRow.js
    │   ├── ExerciseControls.js
    │   ├── ExerciseList.js
    │   └── index.js
    ├── ExerciseScreen.js
    ├── SomeOtherComponent.js
    └── index.js

This doc has been heavily inspired by: https://gist.github.com/ryanflorence/daafb1e3cb8ad740b346 & https://github.com/callstack/react-native-paper. Thank them!

And that's it! I hope this is useful for somebody. Feel free to comment below.

Find me on Twitter as ferrannp.

@digitalbreed
Copy link

I use nearly the same approach, but I'd love to add one thing: I like having a config folder which contains 1. a router.js with all the routers configured (as opposed to your individual files under src), exporting at least the root navigation component; 2. a theme.js containing all my colours and font definitions and whatnot; 3. a bootstrap.js which exports a function I call in my App.js before anything else, used to e.g. setup the default locale for moment, setup my KeyboardManager, disable console.log for non-__DEV__ builds, etc., 4. a constants.js for constants used throughout the app (even though that I find that the more I encapsulate, the less I actually need it)

@StevenBlack
Copy link

Any thoughts on organizing reducers, as the app scales out?

@HishamMubarak
Copy link

Any thoughts on organizing reducers, as the app scales out?

What do you think about this setup? A redux folder inside the src where all actions, reducers and types listed.

├── redux
├── reducers
│ ├── auth_reducer.js
│ ├── score_reducer.js
│ ├── index.js
├── actions
│ ├── auth_actions.js
│ ├── score_actions.js
│ ├── index.js
├── types.js

@ferrannp
Copy link
Author

ferrannp commented Jan 23, 2019

Any thoughts on organizing reducers, as the app scales out?

I follow the Ducks pattern and I don't usually have many reducers. So it would look like:

src
└──redux
     ├── modules
     │  ├── settings.js // Includes reducers, actions and exporting constants (ducks pattern)
     │  └── workouts.js
     └──createStore.js

@jdnichollsc
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment