HomeGuidesReferenceLearn
ArchiveExpo SnackDiscord and ForumsNewsletter

Configure multiple app variants

Learn how to configure app config to install multiple app variants on a single device.


In this chapter, we'll configure our project to run multiple build types (development, preview, production) on a single device simultaneously. This setup will allow us to test various stages of our app development without the need to uninstall and reinstall different versions.

Each variant requires a unique Android Application ID and iOS Bundle Identifier to enable simultaneous installations on one device. Here's how the IDs are set up in our app.json file:

app.json
{
  "ios": {
    "bundleIdentifier": "com.yourname.stickersmash"
    %%placeholder-start%%... %%placeholder-end%%
  },
  "android": {
    "package": "com.yourname.stickersmash"
    %%placeholder-start%%... %%placeholder-end%%
  }
}

1

Convert app.json to app.config.js for dynamic configuration

app.json contains app-related configuration in a JSON file. It's static and isn't ideal if we want to use dynamic values for certain properties. We're going to add different Android Application IDs and iOS Bundle Identifiers for all build profiles based on environment variables.

  • In the code editor, rename app.json to app.config.js.
  • In app.config.js, add environment variables called IS_DEV andIS_PREVIEW for development and preview build profiles:
app.config.js
const IS_DEV = process.env.APP_VARIANT === 'development';
const IS_PREVIEW = process.env.APP_VARIANT === 'preview';
  • Add two functions that dynamically change the app name, Android Application ID and iOS Bundle Identifier:
app.config.js
const getUniqueIdentifier = () => {
  if (IS_DEV) {
    return 'com.yourname.stickersmash.dev';
  }

  if (IS_PREVIEW) {
    return 'com.yourname.stickersmash.preview';
  }

  return 'com.yourname.stickersmash';
};

const getAppName = () => {
  if (IS_DEV) {
    return 'StickerSmash (Dev)';
  }

  if (IS_PREVIEW) {
    return 'StickerSmash (Preview)';
  }

  return 'StickerSmash: Emoji Stickers';
};
  • We'll use getAppName() to assign varying name values for the app and getUniqueIdentifier() to differentiate android.package and ios.bundleIdentifier for development and preview builds:
app.config.js
export default {
  name: getAppName(),
  %%placeholder-start%%... %%placeholder-end%%
  ios: {
    bundleIdentifier: getUniqueIdentifier(),
    %%placeholder-start%%... %%placeholder-end%%
  },
  android: {
    package: getUniqueIdentifier(),
    %%placeholder-start%%... %%placeholder-end%%
  },
};

2

Configure eas.json

In eas.json, add the APP_VARIANT environment variable:

eas.json
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "env": {
        "APP_VARIANT": "development"
      }
    },
    "preview": {
      "distribution": "internal",
      "env": {
        "APP_VARIANT": "preview"
      }
    }
    %%placeholder-start%%... %%placeholder-end%%
  }
}

Running eas build --profile development will now set APP_VARIANT to development.

Note: Since we changed the Android Application ID and iOS Bundle Identifier, the EAS CLI will prompt us to generate a new Keystore for Android and a new provisioning profile for iOS. To learn more about what these steps include, see the previous chapter for more information.

Since our ios-simulator build profile extends development, this configuration is automatically applied for iOS Simulators.

3

Run development server

After builds are complete, follow the same procedure from previous chapters to install them on a device or emulator/simulator.

Since we're identifying our development build with the APP_VARIANT environment variable, we need to pass it to the command when starting the development server. To do this, add a dev script in the "scripts" field of our project's package.json:

package.json
{
  "scripts": {
    "dev": "APP_VARIANT=development npx expo start"
  }
}

Run the npm run dev command to start the development server:

Terminal
npm run dev

This script will evaluate app.config.js locally and load the environment variable for the development profile.

Now, our development build will run on both Android and iOS, displaying the modified app name from app.config.js. For example, the below development build is running on an iOS Simulator. See that the app name is StickerSmash (Dev):

Summary

Chapter 5: Configure multiple app variants

We successfully switched to app.config.js for dynamic settings, added environment variables in eas.json to configure specific build profile, and learned how to start the development server with a custom package.json script.

In the next chapter, learn about what are internal distribution builds, why we need them, and how to create them.

Next: Create and share internal distribution build