React Native: How to change the default folder structure
Tags: reactnative, ios, android
Published: 2020-01-22 18:40:42

###### Cover photo taken from [*Pexels*](https://www.pexels.com/es-es/foto/codigo-datos-efecto-desenfocado-escribiendo-un-guion-2653362/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels)

Hello, 

have you ever had the need to change the default React Native folder structure and you spent hours to figure out the correct setup? 🙌

Well, if this is case in this post I'll highlight all the changes needed to move the folders `android` and `ios` inside a parent folder called `native`.
I assume that the project is created with the command `react-native init`. 

```
From: 

├── ios
├── android

To:

└── native
    ├── ios
    ├── android

```

#Android

Let's start modifying the `package.json` to specify the new root of the android project:

```diff
   "scripts": {
-    "android": "react-native run-android",
+    "android": "react-native run-android --root './native'",
     "ios": "react-native run-ios",

```

Then we need to create a file called `react-native-config.js` that is a file used by the react native CLI where we can modify the project [configuration](https://github.com/react-native-community/cli/blob/master/docs/configuration.md).
In this file we set the source directory of the Android project:

```javascript
module.exports = {
  project: {
    android: {
      sourceDir: './native/android',
    },
  },
}
```

At this point we configured the CLI to locate the android folder but we still need to update the references of the `node_modules` folder in each gradle file.

* `settings.gradle`

```diff
-apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
+apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
```

* `build.gradle`

```diff
         mavenLocal()
         maven {
             // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
-            url("$rootDir/../node_modules/react-native/android")
+            url("$rootDir/../../node_modules/react-native/android")
         }
         maven {
             // Android JSC is installed from npm
-            url("$rootDir/../node_modules/jsc-android/dist")
+            url("$rootDir/../../node_modules/jsc-android/dist")
         }

```

* `app/build.gradle`

```diff
-apply from: "../../node_modules/react-native/react.gradle"
+apply from: "../../../node_modules/react-native/react.gradle"
 
 /**
  * Set this to true to create two separate APKs instead of one:

     into 'libs'
 }
 
-apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+apply from: file("../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)


```

All these changes reflect the moving of the directory one level deeper.


# iOS

In iOS as well we need to modify the `package.json` to specify the new root of the project:

```diff
   "scripts": {
-    "ios": "react-native run-ios",
+    "ios": "react-native run-ios --project-path './native/ios'",


```

Next we need to update the the references of the `node_modules` folder in the native project. 

* `Podfile`

Here I put a partial `diff` of the `Podfile` to highlight the changes needed.

```diff
+    pod 'FBLazyVector', :path => "../../node_modules/react-native/Libraries/FBLazyVector"
-    pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
+    pod 'FBReactNativeSpec', :path => "../../node_modules/react-native/Libraries/FBReactNativeSpec"
-    pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"

```

after the file is update delete the `build` folder inside the iOS project if exist and execute `pod install`.

* `native/ios/<your project name>.xcodeproj/project.pbxproj`

Finally we need to update the script under `Build Phases->Start Packager` in Xcode 

![Build Phases. Start Packager script](https://thepracticaldev.s3.amazonaws.com/i/58a6b2hclq827p6w9hyi.png)


# Extra 

The last thing to do is to update the `.gitignore` file to reflect the changes made.

```diff
 # Android/IntelliJ
 #
-build/
+native/build/

 # CocoaPods
-/ios/Pods/
+native/ios/Pods/
```

#Conclusion


Now the project is ready to be executed using the usual `npm` or `yarn` command 🎉

Let me know in the comments if you know a more straightforward way to achieve the same result!