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.

@jdnichollsc
Copy link

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