Using patch-project

Edit this page

Learn about how to use patch-project to create generate, apply, and preserve native changes in your Expo project.


Note: patch-project is an experimental feature.

patch-project is an Expo config plugin and command-line interface (CLI) tool that generates and applies patches to preserve native changes after running npx expo prebuild. This tool is useful for native app developers who want to preserve customizations without needing to know how to write a config plugin, effectively generating an automatic solution that works with Continuous Native Generation (CNG).

This guide explains how to use patch-project, when to use it, and its limitations.

How patch-project works

patch-project uses an approach to generate and automatically apply patches, which is inspired by Git. Using this command line tool requires the following steps in your project:

Installation

To get started, you need to install the tool in your project:

Terminal
npx expo install patch-project

This command will automatically add the patch-project config plugin to your app config:

app.json
{ "expo": { "plugins": [ "patch-project" %%placeholder-start%% ...%%placeholder-end%% ] } }

Generate patches from existing customizations

Let's assume you manually modified native directories (android and ios) in your project. To generate patches for these native directories, you can run the following command:

Terminal
npx patch-project
Note: In scenarios where you want to generate patches for a specific platform, you can use the --platform option and run npx patch-project --platform android or npx patch-project --platform ios.

These patches, when generated, are saved in the cng-patches directory.

.
app.jsonwith patch-project plugin
cng-patches
  android+eee880ad7b07965271d2323f7057a2b4.patchpatch for android directory
  ios+eee880ad7b07965271d2323f7057a2b4.patchpatch for ios directory
package.json
...other project files

Each file will be prefixed with a platform's name followed by a checksum value. For example:

ios+eee880ad7b07965271d2323f7057a2b4.patch

Apply patches during prebuild

Once you have generated patches, they are automatically applied when subsequently running the npx expo prebuild command. The patch-project config plugin detects the existing patches and applies them to restore your customizations.

When to use patch-project

You can use patch-project in the following scenarios:

  • Migrating existing React Native apps that are complex because they contain extensive native customizations and re-creating these native customizations as config plugins would be time-consuming.
  • Preserving manual changes made to android and/or ios directories while transitioning to adopt Continuous Native Generation (CNG) in your Expo project.
  • Quick prototyping when you need to test native changes before writing config plugins.
  • Patches are applied automatically when running the npx expo prebuild command subsequently. This is an advantage over tools like patch-package (commonly used for generating patches for npm libraries), which do not preserve and automatically apply patches during the prebuild process.

Limitations and considerations

Patches may become invalid during Expo SDK version upgrades because:

  • Template and/or file structure changes: The prebuild template evolves between SDK versions with new changes and file updates in native directories. This will affect the already generated diff in the cng-patches directory, which may no longer apply.
  • Plugin conflicts: CNG patches can be dangerous and may break when other plugins modify the same files. For example, if you add a new plugin that updates MainApplication.kt and conflicts with your existing patches, the patches may no longer apply correctly. In such cases, you may need to regenerate patches.
  • iOS .pbxproj changes: In iOS projects, applying patches to .pbxproj files can be fragile since this file contains UUIDs and running a command like npx expo prebuild --clean can change these IDs. For example, if you're adding a widget extension or making other project configuration changes, patch-based approaches may not work reliably. You can review the generated cng-patches/ios-* and keep only the necessary patch. Having the patch as minimal as possible would reduce the risk of failures when applying patches.

It is recommended to regenerate patches after each SDK upgrade.