- 📦 Download and Setup
- ✍️ Editing SDK Packages
- ⏱ Testing Your Changes
- 📚 Updating Documentation
- 📝 Writing a Commit Message
- 🔎 Before Submitting
Thanks for the help! We currently review PRs for packages/
, docs/
, templates/
, guides/
, apps/
, and markdown files.
Expo for Web code is easy to test and contribute to compared to the native code, and we welcome all contributions to it. You may find that some of the web features you are looking for actually live in the expo-cli repo.
We recommend that folks interested in contributing to the SDK use the apps/bare-expo
project in their SDK development workflow instead of the Expo client. The Expo client itself (in the ios/
and android/
directories) are difficult to setup and require API tokens.
The bare-expo
project includes most of the Expo SDK and runs the JavaScript code from apps/test-suite
to allow you to easily write and run E2E tests for iOS, Android, and web for any given SDK package. Unit tests can be written within the SDK package itself. When pushed to the remote, CI will run this project with Detox for Android/iOS and Puppeteer for web and report the results on your pull request.
Manual smoke tests are included in apps/native-component-list
, this is a good fit for demos or tests that require physical interactions. This is particularly useful if you are testing interactions with UI components, or there is something that is very difficult to test in an automated way but would be easy to verify through manual interaction.
💡 How does
bare-expo
relate totest-suite
?
bare-expo
is a bare workflow app that links all of the Expo SDK dependencies in thepackages/
directory in order to be able to run projects in theapps/
directory in the bare workflow rather than the Expo client. It currently only runstest-suite
.test-suite
is a regular managed workflow Expo app with some custom code to turn it into a test runner. If you runexpo start
in thetest-suite
directory you can load the project in Expo client.bare-expo
imports thetest-suite
app root component and uses it as its own root component.
💽 The development environment for this repository does not support Windows. To contribute from Windows you must use WSL.
-
Fork this repository to your own GitHub account and then clone it to your local device. (
git remote add upstream [email protected]:expo/expo.git
😉). You can usegit clone --depth 1 --single-branch --branch main [email protected]:expo/expo.git
, discarding most of branches and history to clone it faster. -
Ensure direnv is installed on your computer.
-
Ensure Node 14 is installed on your computer. (Check version with
node -v
) -
If you will be working with the iOS project, ensure ruby 2.7 is installed on your machine. macOS comes with ruby 2.6, which will give you issues; if you use homebrew you can just run
brew install [email protected]
. -
Run the setup script with:
npm run setup:native
(if you just want to contribute to the docs, you can runnpm run setup:docs
). This command does the following for you:- Downloads submodules (like
react-native
) withgit submodule update --init
- Fetches files with git lfs, which we use for big native libraries like Google Mobile Vision. Note: you must have
git lfs
already installed. - Ensures Yarn is installed
- Ensures your computer is set up for React Native (will install the Android NDK if it's not present)
- Downloads the Node packages (
yarn install
)
Make sure that you're using Java 8 (e.g. OpenJDK 1.8.0_292).
ANDROID_SDK_ROOT
,ANDROID_NDK_HOME
environmental variables should be set or configured vialocal.properties
file inandroid
folder of the native project you're working with. - Downloads submodules (like
-
Navigate to the bare sandbox project
cd apps/bare-expo
-
Run the project on any platform (maybe start with web; it's the fastest! 😁)
- Web:
yarn web
- iOS:
yarn ios
- Android:
yarn android
If you are working on a Linux distribution, make sure to set the
TERMINAL
environment variable to your preferred terminal application. (e.g.export TERMINAL="Konsole"
) - Web:
-
You are now running the
test-suite
app via thebare-expo
project. The next section explains how you can begin to make changes to SDK packages.
If this didn't work for you as described, please open an issue.
All Expo SDK packages can be found in the packages/
directory. These packages are automatically linked to the projects in the apps/
directory, so you can edit them in-place and see the changes in the running app.
- Navigate to a package you want to edit. Ex:
cd packages/expo-constants
- Start the TypeScript build in watch mode:
yarn build
- Edit code in that package's
src/
directory - Play with your changes on a simulator or device through
bare-expo
:- Add or modify a file named after the API you're working on. Ex:
apps/test-suite/tests/Constants.js
- To see native changes, you will need to run the
test-suite
with theapps/bare-expo
project usingyarn <android | ios | web>
. - If you are only making JavaScript changes, you can run
test-suite
from theapps/test-suite
project usingexpo start
. - To run the full test suite with Puppeteer or Detox, you can run the tests
yarn test:<android | ios | web>
.
- Add or modify a file named after the API you're working on. Ex:
- You can edit a package's native code directly from its respective folder in the
packages/
directory or by openingbare-expo
in a native editor:- Navigate to the
bare-expo
app directory:cd apps/bare-expo
- Android Studio:
yarn edit:android
- Xcode:
yarn edit:ios
- Remember to rebuild the native project whenever you make a native change
- Navigate to the
All modules should adhere to the style guides which can be found here:
- Guide to Unimodule Development
- Expo JS Style Guide (also mostly applies to TypeScript)
- Updating Changelogs
- The React Native dev tools are currently disabled in our fork #5602. You can hack around this by cloning React Native outside this repo, then copying the contents
react-native/React/DevSupport
intoexpo/react-native-lab/react-native/React/DevSupport
(this will only enable the shake gesture, CMD+R won't work yet). - We use a fork of
react-native
in this repo; this fork is located atreact-native-lab/react-native
(you can make changes or cherry-picks from here if you want). It diverges the minimal amount necessary from thereact-native
version in itspackage.json
. - All of the package's
build/
code should be committed. This is because it is simpler to reproduce issues if all contributors are running the same code and so we don't need to rebuild dozen of packages locally on everygit pull
orgit checkout
operation. - We use a unified set of basic Bash scripts and configs called
expo-module-scripts
to ensure everything runs smoothly (TypeScript, Babel, Jest, etc...).
You'll need write about how you tested your changes in the PR under the Test Plan section.
The best way to get your changes merged is to build good tests for them! We have three different kinds of tests: unit-tests, automated E2E tests, and demos (adding tests that you notice are missing is a great way to become my friend 🥳)!
- Create a test for your feature in the appropriate package's
src/__tests__
directory (if the file doesn't exist already, create it with the*-test.ts
or*-test.tsx
extension). - Any new bridged native functions have to be added to the jest-expo package to ensure they are mocked. To help you do this more easily, we've written a tool and a guide on how to do this. Check out Generating Jest Mocks!
- Run the test with
yarn test
and ensure it handles all platforms (iOS, Android, and web). If the feature doesn't support a platform, then you can exclude it by putting your test in a file with a platform extension like:-test.ios.ts
,-test.native.ts
,-test.web.ts
... - You can also test platforms one at a time by pressing X and selecting the platform you want to test!
- Write your tests in
apps/test-suite/tests
- These tests are written with a non-feature-complete version of Jasmine that runs on the Android and iOS clients, so no special features like snapshot testing will be available.
- If you created a new test file, be sure to add it in
apps/test-suite/TestUtils.js
. This is where you can do platform exclusion. Useglobal.DETOX
to test for iOS tests, andExponentTest.isInCI
to test for Android Device Farm.
- Run your tests locally from the
bare-expo
directory withyarn test:android
,yarn test:ios
, oryarn test:web
.- It's important you test locally because native CI tests can be fragile, take a while to finish, and be frustrating when they fail.
- When testing for web, you can set
headless: false
in theapps/bare-expo/jest-puppeteer.config.js
to watch the tests live. You can also executeawait jestPuppeteer.debug();
inapps/bare-expo/e2e/TestSuite-test.web.js
to pause the tests and debug them!
- Remember to try and get your feature running on as many platforms as possible.
Thanks again for helping to make sure that Expo is stable for everyone!
Our docs are made with Next.js. They're located in the docs/
directory. For more information look at the docs/readme.md
.
TL;DR:
- Navigate to the
docs/
directory and runyarn
. - Start the project with
yarn dev
(make sure you don't have another server running on port3000
). - Navigate to the docs you want to edit:
cd docs/pages/versions/unversioned/
- If you update an older version, ensure the relevant changes are copied into
unversioned/
If this is your first time committing to a large public repo, you could look through this neat tutorial: "How to Write a Git Commit Message"
Commit messages are most useful when formatted like so: [platform][api] Title
. For example if you fix a bug in the package expo-video
for iOS, you could write: [ios][video] Fixed black screen bug that appears on older devices
.
To help keep CI green, please make sure of the following:
- Remember to add a concise description of any user-facing changes to
CHANGELOG.md
file in the package you've changed or root's CHANGELOG.md if your changes don't apply to any package. This is especially helpful for breaking changes! - If you modified anything in
packages/
:- You transpiled the TypeScript with
yarn build
in the directory of whichever package you modified. - Run
yarn lint --fix
to fix the formatting of the code. Ensure thatyarn lint
succeeds without errors or warnings. - Run
yarn test
to ensure all existing tests pass for that package, along with any new tests you would've written. - All
console.log
s or commented out code blocks are removed! :]
- You transpiled the TypeScript with
- If you edited the
docs/
:- Any change to the current SDK version should also be in the unversioned copy as well. Example:
- You fixed a typo in
docs/pages/versions/vXX.0.0/sdk/app-auth.md
- Ensure you copy that change to:
docs/pages/versions/unversioned/sdk/app-auth.md
- You fixed a typo in
- You don't need to run the docs tests locally. Just ensure the links you include aren't broken, and the format is correct!
- Any change to the current SDK version should also be in the unversioned copy as well. Example:
- Our CI tests will finish early if you didn't make changes to certain directories. If you want to get results faster then you should make changes to
docs/
in one PR, and changes to anything else in another!