Skip to main content

Adding Expo to a project

  • Supported RN Version: 0.85.x
  • Supported Expo Version: 56.x
SDK 56 defaults

Expo SDK 56 ships Hermes V1 as the default JavaScript engine and installs expo/fetch as the global fetch implementation (WinterTC-compliant). Archibald adopts both defaults. Icon fonts come from the scoped @react-native-vector-icons/* packages (the deprecated @expo/vector-icons is no longer installed), and navigation primitives are imported from expo-router / expo-router/react-navigation — expo-router no longer depends on React Navigation.

Overview

Expo is a framework which makes it possible to use react-native easily and without the hassle of managing local builds, needing an Mac etc. On top it also has functionality for CI/CD, Push and over the air updates.

Preconditions

Please follow the normal setup you need for the respective platform if you want to develop with it, except Managed Workflow. Xcode + cocoapods with iOS and Android Studio + Java for android. There are environment setup guids on the internet.

There are environment setup guids on the internet. Android Setup

Getting Started

After you bootstrapped a new project create a new project you can add expo to the project with the help of the add command.

Switch into your project and call npm run archibald add expo. It will create a platform folder in src with the name you chose before and the template you chose before.

Afterwards you can start the project with adding --native and the respective --platform={YOUR_PLATFORM} to your serve or build command.

That will run a fully managed expo build, which can then be consumed with the Expo Go app on your phone.

If you don't want to always provide --native to your build, you can configure the field cli.native.expo.platforms and put into an array all platforms which should be treated as native. The commands serve, build and test(jest also directly) respect this configuration.

If you want to install it on your phone you can use the command --native=ios|android which then will run and create projects which can be used.

tip

You need a Mac for using the --native=ios command.

Experiments

The cli.native.expo.experiments object toggles opt-in native behavior:

FlagDefaultDescription
treeShakingfalseEnables Expo's experimental Metro tree shaking (EXPO_UNSTABLE_TREE_SHAKING).
workletsBundleModefalseEnables react-native-worklets Bundle Mode — mitigates the Hermes V1 + reanimated memory regression on SDK 56. Requires the worklets "seamless Metro bundling" patch (setup); without it Metro fails with Failed to get the SHA-1 for … /.worklets/*.js because the plugin generates worklet modules into node_modules after Metro's file map is built. Leave off until that patch is applied.
generateRouterTypestrue (shop)Generates expo-router typed routes for the native platform (see below).

Type-safe routes

With cli.native.expo.experiments.generateRouterTypes enabled, serve/build for a native platform generate expo-router's route union so router.push('/…'), <Link href> and dynamic params are type-checked against the actual router tree — router.push('/does-not-exist') becomes a compile error.

Generation is non-polluting: the committed tsconfig.json is never modified. Three artifacts are written and are git-ignored (never committed):

  • .expo/types/router.d.ts — the generated route union.
  • expo-env.d.ts — Expo's ambient type reference.
  • tsconfig.native.json — an overlay that extends the committed tsconfig.json and adds only the includes that surface the generated types.

Enforcement is wired into the existing type-checking test runner — no separate tsc step. Running the native tests regenerates the union first, then the type-checking runner includes it, so a bogus route fails the test run:

archibald test --native=app # regenerates the route union, then type-checks against it

The union is also regenerated on every native serve/build, so your editor picks up the overlay (tsconfig.native.json) after the first generation.

note

The generator uses @expo/router-server internals (the same ones expo customize uses). It is guarded by that package's version export (>= 52) and fails soft (logs a warning, skips generation) if the internals move — re-verify after each Expo SDK bump.

Troubleshooting

  • If you run into the problem try arch -x86_64 sudo gem install ffi first
  • Outdated since July 2022 if you still have that problem uninstall and reinstallation cocoapods
  • M1 Mac iOS