Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Ycfx/838a9c84a1dec2574cccca9a38cb86b4 to your computer and use it in GitHub Desktop.
Save Ycfx/838a9c84a1dec2574cccca9a38cb86b4 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

Scenes or Screens concept

src
└── scenes
    ├── 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
├── scenes
│   ├── 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 scenes 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
├── scenes
├── 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.

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