new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Expo & React Native · all subjects

eas services

72 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

Code signing verification process

When the app downloads an update, the server responds with the update and its generated signature. After being downloaded but before being applied, the update is verified against the embedded certificate and included signature. The update is applied if the certificate and signature are valid, and rejected otherwise.

Key rotation definition and purpose

Key rotation is the process by which the key pair used for signing updates is changed. It is performed in response to key expiration (after the certificate validity duration), private key compromise (if the private key is exposed), or as a security best practice to periodically rotate keys to ensure system resilience.

Key expiration and update application

After a certificate expires, updates signed with the corresponding private key will no longer be applied after being downloaded by the app. However, updates downloaded before the expiration of their signing certificate will continue to function normally. This means users must receive a new build with a new certificate before the old certificate expires.

Key rotation procedure

To rotate keys: (1) Back up the old keys and certificate. (2) Generate a new key by running the generation command from step 1, optionally changing the keyid in updates.codeSigningMetadata.keyid in app.json for debugging. (3) Set a new runtime version for builds using the new certificate to ensure only updates signed with the new key run in the new build. (4) Publish signed updates using the new key with the eas update command.

Removing code signing from an app

Removing code signing can be thought of as a key rotation to a null key. The procedure is: (1) Backup the old key and certificate. (2) Remove the updates.codeSigningMetadata field from app.json. (3) Set a new runtime version for builds to ensure that only unsigned updates run in the new build.

EAS Update code signing availability

EAS Update Code Signing is only available to accounts subscribed to the EAS Production or Enterprise plans.

Code signing mechanism in EAS Update

The expo-updates library supports end-to-end code signing using public-key cryptography. Developers can cryptographically sign updates with their own keys, and signatures are verified on the client before the update is applied. This ensures that ISPs, CDNs, cloud providers, and even EAS itself cannot tamper with updates.

Generate code signing key pair command

Run `npx expo-updates codesigning:generate --key-output-directory ../keys --certificate-output-directory certs --certificate-validity-duration-years 10 --certificate-common-name "Your Organization Name"` to generate a key pair and code signing certificate. The command creates three files: ../keys/private-key.pem (private key), ../keys/public-key.pem (public key), and certs/certificate.pem (code signing certificate valid for the specified duration).

Private key storage for code signing

The generated private key must be kept private and secure. It is recommended to store the private key outside of source control in a directory separate from the project, and to store it using the same methods as other sensitive information (KMS, password manager, etc.).

Public key and certificate storage for code signing

The public key may be stored alongside the private key but is not sensitive. The certificate should be included in the project and checked into source control. It contains the public key and a method for verifying code signatures, and is used to verify the update's signature when a signed update is downloaded.

Certificate validity duration considerations

The certificate validity duration may vary based on the security needs of the app. A shorter validity duration requires key rotation more frequently and is considered better practice since a compromised private key will have sooner expiration limiting exposure, but adds overhead to the app's release process. Longer validity durations reduce rotation frequency but increase risk if a key is compromised. Expo uses 20 years for the public Expo Go app, 1 year for internal apps distributed more frequently, and plans to rotate keys every 10 years.

Configure code signing command

Run `npx expo-updates codesigning:configure --certificate-input-directory certs --key-input-directory ../keys` to configure code signing in your project.

Code signing configuration with CNG

If using Continuous Native Generation (CNG) to generate native projects, the app.json configuration generated by `npx expo-updates codesigning:configure` is all that is needed. The changes will be applied to the native projects the next time they are generated.

Code signing app.json configuration format

When code signing is configured, the app.json includes the following configuration under the "expo.updates" section: "codeSigningCertificate" (path to certificate file), and "codeSigningMetadata" object with "keyid" (string, typically "main") and "alg" (string, typically "rsa-v1_5-sha256").

Android code signing configuration without CNG

For projects not using CNG, code signing must be configured in android/app/src/main/AndroidManifest.xml by adding two meta-data fields to the <application> element: one named "expo.modules.updates.CODE_SIGNING_CERTIFICATE" with an XML-escaped certificate value, and one named "expo.modules.updates.CODE_SIGNING_METADATA" with value "{\"keyid\":\"main\",\"alg\":\"rsa-v1_5-sha256\"}". To create the XML-escaped certificate, copy contents of certificate.pem and replace all \r with &#xD; and \n with &#xA;.

iOS code signing configuration without CNG

For projects not using CNG, code signing must be configured in ios/project-name/Supporting/Expo.plist by adding two keys to the <dict> element: EXUpdatesCodeSigningCertificate (string value containing XML-escaped certificate where \r is replaced with &#xD; but \n is not escaped), and EXUpdatesCodeSigningMetadata (dict with keys "keyid" (string "main") and "alg" (string "rsa-v1_5-sha256")).

Publish signed update command

Run `eas update --private-key-path ../keys/private-key.pem` to publish a signed update for your app. During the EAS Update publish, the CLI automatically detects code signing configuration, verifies the integrity of the update, creates a digital signature using the private key locally (so the private key never leaves the machine), and sends the signature to EAS to store alongside the update.

AppDelegate setup for EAS Update on iOS SDK 52

AppDelegate should: (1) extend EXAppDelegateWrapper, (2) provide a public static shared() method to get the AppDelegate instance, (3) maintain a var updatesController reference of type InternalAppControllerInterface, (4) override bundleUrl() to return updatesController?.launchAssetUrl() if available or a bundled URL, (5) in didFinishLaunchingWithOptions set moduleName='App', initialProps=[:], rootViewFactory=createRCTRootViewFactory(), and call AppController.initializeWithoutStarting().

Migration from CodePush to EAS Update

Developers migrating from CodePush to EAS Update should reference the Migrating from CodePush guide for additional information on the transition process.

What EAS Update does for your app after release

EAS Update enables over-the-air updates for native Android and iOS apps. After integrating it, the app can receive JavaScript bundle updates from the updates system without requiring an app store submission, using the managed AppController that starts during app launch and loads the latest update or embedded bundle.

EAS Update in brownfield native apps with Expo SDK 52+

EAS Update can be integrated into existing native Android and iOS apps that have React Native installed. This guide applies to Expo SDK 52 or later and React Native 0.76 or later. For greenfield React Native apps (built with React Native from the start with React Native as the entry point), use the Get started with EAS Update guide instead.

Prerequisites for EAS Update integration in native apps

Prerequisites are: (1) A brownfield native project with React Native installed and configured to render a root view, following React Native's Integration with Existing Apps guide. (2) Latest Expo SDK version and its supported React Native version. (3) No other update libraries (remove react-native-code-push or similar). (4) Expo modules installed and configured in the project. (5) metro.config.js must extend expo/metro-config. (6) babel.config.js must extend babel-preset-expo. (7) npx expo export -p android and npx expo export -p ios must run successfully.

Disable automatic updates initialization on Android

Modify android/gradle.properties to disable automatic updates initialization by setting a property that prevents expo-updates from automatically setting itself up in a way that only supports greenfield React Native projects.

Disable automatic updates initialization on iOS

Pass the environment variable EX_UPDATES_CUSTOM_INIT=1 when running pod-install to disable automatic updates initialization. Use the command: EX_UPDATES_CUSTOM_INIT=1 npx pod-install (npm), EX_UPDATES_CUSTOM_INIT=1 yarn dlx pod-install (yarn), EX_UPDATES_CUSTOM_INIT=1 pnpm dlx pod-install (pnpm), or EX_UPDATES_CUSTOM_INIT=1 bunx pod-install (bun).

Metro config for brownfield EAS Update

Ensure metro.config.js extends Expo's metro config using getDefaultConfig from expo/metro-config. Example: const { getDefaultConfig } = require('expo/metro-config'); const config = getDefaultConfig(__dirname); module.exports = config;

Custom entry point with registerRootComponent for EAS Update

Use Expo's registerRootComponent() in custom entry points. This registers the component with the react-native AppRegistry and performs all required Expo initialization including expo-updates setup. Example: import App from './App'; import { registerRootComponent } from 'expo'; registerRootComponent(App);

Custom entry point with direct AppRegistry for EAS Update

If keeping an existing entry point using AppRegistry directly, add a call to Expo initialization before registering the app. Import 'expo/src/Expo.fx' before AppRegistry.registerComponent(). Example: import App from './App'; import 'expo/src/Expo.fx'; import { AppRegistry } from 'react-native'; function getApp() { return <App />; } AppRegistry.registerComponent('App', () => getApp());

MainApplication.kt setup for EAS Update on Android

MainApplication class should: (1) implement ReactApplication, (2) override reactHost to use ExpoReactHostFactory.getDefaultReactHost() with applicationContext and packageList parameters, (3) in onCreate() call loadReactNative(this) and ApplicationLifecycleDispatcher.onApplicationCreate(this), (4) override onConfigurationChanged to call ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig).

MainActivity.kt setup for EAS Update on Android

MainActivity class should: (1) subclass com.facebook.react.ReactActivity, (2) override getMainComponentName() to return the app name registered in the JS entry point, (3) override createReactActivityDelegate() using ReactActivityDelegateWrapper that wraps DefaultReactActivityDelegate, passing this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, and a DefaultReactActivityDelegate instance.

CustomViewController setup for EAS Update on iOS SDK 52

CustomViewController should: (1) implement AppControllerDelegate, (2) in init set appDelegate.updatesController to AppController.sharedInstance, set AppController.sharedInstance.delegate to self, and call AppController.sharedInstance.start(), (3) implement appController(_:didStartWithSuccess:) that calls createView(), (4) in createView() get the rootViewFactory from appDelegate.reactNativeFactory, create a root view with withModuleName matching appDelegate.moduleName, and add it to the view controller with layout constraints to safeAreaLayoutGuide edges.

Channel surfing for production preview with internal users

Teams can roll out an update in production to a small set of internal users using channel surfing for a known subset of users. This approach should only be used with users who can report and recover from preview update issues because a broken update can prevent them from reaching the UI that clears the channel override.

Development builds for previewing updates

Development builds are a great way to preview updates from pull requests, directly from the EAS dashboard, or from the built-in UI provided by the expo-dev-client library.

Preview builds for non-technical users

Non-technical users can test changes from a preview build on an app store testing track or internal distribution. For smaller teams, a single preview build can be deployed to an app store testing track or internal distribution, and updates can be published to the channel used by that preview build.

Channel surfing in preview builds

A mechanism can be built into a preview build that allows users to select a different update or channel to load at runtime. This is useful when the app runtime does not change often and many different updates can be loaded in the same app.

Testing updates in production-like environment before deployment

Before deploying an update to production, it is often necessary to test it in a production-like environment. There are different approaches available for previewing updates depending on whether you are using development builds, preview builds, or production builds.

Environment variable size limitations

Environment variable value size is limited to 32 KiB for environment variables with secret visibility and 4 KiB for other visibility types.

Environment variable quota per Expo account and project

You can create up to 150 account-wide environment variables for each Expo account and 200 project-specific environment variables for each app.

Custom environment limitations

Custom environments are limited to 10 per project. When creating a custom environment, an environment name can contain letters, digits, underscores and hyphens, and must be between 3-100 characters.

Environment variables with secret visibility are not readable outside EAS servers

Environment variables with secret visibility are not readable outside of EAS servers and cannot be pulled locally for development or bundled into app JavaScript code for updates.

eas env:pull command for local development

The eas env:pull command pulls environment variables from EAS servers to the local .env file for development. The development environment is the default environment for this purpose, as it is used for development builds.

Create EAS environment variable with CLI

To create a new environment variable, use the command: eas env:set --name EXPO_PUBLIC_API_URL --value https://api.example.com --environment production --visibility plaintext. The --name parameter specifies the variable name, --value specifies the value, --environment specifies which environment (development, preview, production), and --visibility specifies the visibility type (plaintext, sensitive, or secret).

Pull environment variables for local development

Environment variables can be pulled locally for development using the eas env:pull command, which allows you to use the same set of environment variables for your local environment as for EAS jobs.

EAS Update with environment variables

To use environment variables with EAS Update, run the eas update command with the --environment flag: eas update --environment production. Only environment variables from the specified environment will be used during the update process.

EAS Hosting with environment variables

To use environment variables with EAS Hosting, run eas deploy with the --environment flag: eas deploy --environment production. If you need both client and server side environment variables, run eas env:pull --environment production, then npx expo export --platform web, then eas deploy --environment production in that order. Client-side variables must be plain text or sensitive, not secret.

Project-wide vs account-wide environment variables

Project-wide environment variables are specific to a single EAS project and managed via the Environment variables page in the project dashboard. Account-wide environment variables are available across all projects in an EAS account and managed via the Environment variables page in the account dashboard. Both types are available in jobs that run on EAS servers and updates, with account-wide variables combined with project-wide variables for a specific project.

EAS environment variable types

There are two types of EAS environment variables: Strings (standard key/value pairs used across builds, updates, workflows, and hosting) and Files (values uploaded as files such as google-services.json or certificates that are made available to jobs as file paths on the build runner).

Plain text visibility for environment variables

Plain text visibility is visible on the website, in EAS CLI, and in logs. This is suitable for non-sensitive values.

Sensitive visibility for environment variables

Sensitive visibility means the environment variable is obfuscated in EAS Build and Workflows job logs. Users can toggle to make them visible on the website, and they are also readable in EAS CLI.

Secret visibility for environment variables

Secret visibility means the environment variable is not readable outside of EAS servers, including on the website and in EAS CLI. Secrets are obfuscated in EAS Build and Workflows job logs. Secret environment variables are intended to provide values to EAS Build or Workflows jobs to alter how a job runs, such as setting an NPM_TOKEN to install private packages from npm. Secrets do not provide additional security for values embedded in the application itself.

Client-side environment variables visibility

Anything included in client-side code should be considered public and readable to any individual that can run your app. When using environment variables with EAS Hosting, client-side variables must be plain text or sensitive, not secret.

Environment variables scoped to single vs multiple environments

Environment variables can be assigned to multiple environments and have the same value across all of them, or be created for a single environment.

EAS environment variables overview

EAS environment variables are configured in EAS via the EAS CLI or on the expo.dev dashboard and can be accessed by EAS Build, EAS Workflows, and your local machine via EAS CLI. They solve the problems of keeping configuration in one place for cloud builds, updates, and workflows without committing .env files; separating values by environment (development, preview, production) while reusing names; controlling visibility so only the right surfaces can read each value; and applying the same set locally or inside CI/CD.

Local .env files not available for remote jobs

During local development, environment variables are loaded from local .env or .env.local files. These files are generally excluded from version control and are not available for jobs that run on a remote server, such as EAS Build and EAS Workflows.

Default EAS environments

By default, EAS supports three environments for environment variables: development, preview, and production. Custom environment names are available on Enterprise and Production plans.

EAS free access limits and reset period

Expo Application Services (EAS) offers free access to a limited quantity of low-priority builds on EAS Build and free updates with EAS Update. These limits reset monthly.

Monthly active user (MAU) definition for EAS Update billing

A monthly active user (MAU) is a unique user of an app that downloads at least one update via EAS Update within a single monthly billing period.

Expo Application Services (EAS)

Expo Application Services (EAS) is a set of services that complement the Expo framework in each step of the development process.

Reconnecting after Supabase disconnect

After you disconnect, connect no longer sees a linked project, so it creates a new one. To point the app back at the same project, run 'connect --link' with its reference ID.

EAS CLI Supabase integration command

Run 'eas integrations:supabase:connect' to automate the standard Supabase setup, which authorizes your Supabase account, creates or links a project, installs the SDK, and writes environment variables. To use an existing Supabase project, run 'eas integrations:supabase:connect --link <project-ref-or-url>'.

eas integrations:supabase:connect behavior

The connect command opens your browser to authorize Supabase, asks which organization to use if your account has more than one, asks for a region from Americas, Europe/Middle East/Africa, or Asia Pacific, installs @supabase/supabase-js and expo-sqlite with its config plugin, and writes EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_PUBLISHABLE_KEY to .env.local and EAS environment variables across Production, Preview, and Development environments. Re-running connect is safe and prompts before overwriting environment variables.

Give your agent this brain