Why not Windows or Linux? (click to expand)
It’s primarily because Apple only supports iOS development using macOS. It’s true that we could support web, server, and Android development on other operating systems, but because of the Apple requirement, all of our active developers currently run macOS. We’d very much welcome a PR to build out support on Windows or Linux!
Unfortunately the dev environment is overall pretty heavy. You’ll ideally want a machine with at least 32 GiB of RAM, although 16 GiB should suffice.
# Prerequisites
## Xcode
Go to the [Mac App Store](https://apps.apple.com/us/app/xcode/id497799835) to install Xcode, or if you already have it, to update it to the latest version.
Once Xcode is installed, open it up. If you are prompted, follow the instructions to install any “Additional Required Components”.
Finally, you need to make sure that the “Command Line Tools” are installed. Go to Xcode → Preferences → Locations, and then install the tools by selecting the most recent version from the Command Line Tools dropdown.
## Homebrew
Install [Homebrew](https://brew.sh/), a package manager for macOS.
## Node
Next, install [Node](https://nodejs.org/) using Homebrew.
```
brew install node; brew upgrade node
```
The reason we use both `install` and `upgrade` is that there’s no single Homebrew command equivalent to “install if not installed, and upgrade if already installed”.
## Yarn
We use the [Yarn](https://yarnpkg.com/) package manager for JavaScript in our repo.
```
brew install yarn; brew upgrade yarn
```
## Watchman
Watchman is a tool from Facebook used in the React Native dev environment to watch for changes to your filesystem.
```
brew install watchman; brew upgrade watchman
```
## nvm
Node Version Manager is a tool that helps us make sure we use the same version of Node on our server between prod and dev environments.
```
brew install nvm; brew upgrade nvm
```
After installing, Homebrew will print out some instructions under the Caveats section of its output. It will ask you to do two things: `mkdir ~/.nvm`, and to add some lines to your `~/.bash_profile` (or desired shell configuration file). We recommend that you append `--no-use` to the line that loads nvm, so that you continue to use your Homebrew-sourced Node distribution by default:
```
export NVM_DIR="$HOME/.nvm"
[ -s "/usr/local/opt/nvm/nvm.sh" ] && . "/usr/local/opt/nvm/nvm.sh" --no-use # This loads nvm
[ -s "/usr/local/opt/nvm/etc/bash_completion.d/nvm" ] && . "/usr/local/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion
```
Now either close and reopen your terminal window or re-source your shell configuration file in order to load nvm:
```
source ~/.bash_profile
```
## MySQL
For now we’re using MySQL 5.7 as the primary server-side database. Hopefully we’ll change this soon, but for now, install MySQL 5.7 using Homebrew.
```
brew install mysql@5.7; brew upgrade mysql@5.7
```
Next we’ll configure MySQL to start when your computer boots using `brew services`:
```
brew tap homebrew/services
brew services start mysql@5.7
```
We’ll also want to link MySQL so that you can run CLI commands:
```
brew link mysql@5.7 --force
```
Finally, you should set up a root password for your local MySQL instance:
```
mysqladmin -u root password
```
## Redis
We use Redis on the server side as a message broker.
```
brew install redis; brew upgrade redis
```
We’ll set it up to start on boot with `brew services`:
```
brew services start redis
```
## CocoaPods
CocoaPods is a dependency management system for iOS development. React Native uses it to manage native modules.
```
sudo gem install cocoapods
```
In order for `pod` to be accessible from the command-line, we’ll need to update your `$PATH` environmental variable. Open your `~/.bash_profile` (or desired shell configuration file) and add the following line:
```
export PATH=$PATH:/usr/local/lib/ruby/gems/2.7.0/bin
```
Make sure you reload the `~/.bash_profile` after editing it:
```
source ~/.bash_profile
```
## React Native Debugger
The React Native Debugger allows you to step through Javascript execution, track Redux state, and inspect the React component tree.
```
brew install react-native-debugger; brew upgrade react-native-debugger
```
## Reactotron
Reactotron is an event tracker and logger that can be used to aid in debugging on React Native.
```
brew install reactotron; brew upgrade reactotron
```
## JDK
We’ll need the Java Development Kit for Android development.
```
brew install adoptopenjdk/openjdk/adoptopenjdk8; brew upgrade adoptopenjdk/openjdk/adoptopenjdk8
```
## Android Studio
Start by downloading and installing [Android Studio](https://developer.android.com/studio/index.html). When prompted to choose an installation type, select “Custom”. Make sure you check the boxes for the following:
* `Android SDK`
* `Android SDK Platform`
* `Performance (Intel ® HAXM)`
* `Android Virtual Device`
### Android SDK
Android Studio installs the latest Android SDK by default, but since React Native uses the Android 10 SDK specifically, we’ll need to install it using Android Studio’s SDK Manager. You can access the SDK Manager from the “Welcome to Android Studio” screen that pops up when you first open the application, under “Configure”. If you already have a project open, you can access it from Tools → SDK Manager.
Once you have the SDK Manager open, select the “SDK Platforms” tab, and then check the box for “Show Package Details”. Now expand the “Android 10 (Q)” section, and make sure the following subsections are checked:
* `Android SDK Platform 29`
* `Intel x86 Atom_64 System Image` or `Google APIs Intel x86 Atom System Image`
Next, select the “SDK Tools” tab, and check the box for “Show Package Details”. Expand the “Android SDK Build-Tools” section, and make sure that the “29.0.2” subsection is checked.
To finish the SDK Manager step, click “Apply” to download and install everything you’ve selected.
### Enable Android CLI commands
You’ll need to append the following lines to your `~/.bash_profile` (or desired shell configuration file) in order for React Native to be able to build your Android project.
```
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/tools/bin
export PATH=$PATH:$ANDROID_HOME/platform-tools
export JAVA_HOME="/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home"
```
Now either close and reopen your terminal window or re-source your shell configuration file in order to run the new commands:
```
source ~/.bash_profile
```
## Arcanist
We use Phabricator for code review. To upload a “diff” to Phabricator, you’ll need to use a tool called Arcanist.
To install Arcanist, we’ll need to clone its Git repository. Pick a place in your filesystem to store it, and then run this command:
```
git clone https://github.com/phacility/arcanist.git
```
Next, you’ll need to add the path `./arcanist/bin` to your `$PATH` in your `~/.bash_profile` (or desired shell configuration file):
```
export PATH=$PATH:~/src/arcanist/bin
```
Make sure to replace the `~/src` portion of the above with the location of the directory you installed Arcanist in.
# Configuration
## Apache
In both dev and prod environments we have Node configured to run on port 3000, with Apache proxying it across to port 80. The reason for Apache is so that we can use other tech stacks alongside Node. In particular, we’ve been using a MySQL administration web frontend called PHPMyAdmin.
macOS comes with an Apache installation built in. We just need to configure it a little bit.
First, we’ll edit the main Apache configuration file.
```
sudo vim /private/etc/apache2/httpd.conf
```
The following individual lines each need to be uncommented:
```
LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
LoadModule proxy_wstunnel_module libexec/apache2/mod_proxy_wstunnel.so
LoadModule userdir_module libexec/apache2/mod_userdir.so
LoadModule php7_module libexec/apache2/libphp7.so
Include /private/etc/apache2/extra/httpd-userdir.conf
```
Next, we’ll edit the `http-userdir.conf` file.
```
sudo vim /private/etc/apache2/extra/httpd-userdir.conf
```
The following line needs to be uncommented:
```
Include /private/etc/apache2/users/*.conf
```
Now for the main course. We need to set up a configuration file for the current user.
```
sudo vim /private/etc/apache2/users/$USER.conf
```
```