HomeGuidesReferenceLearn
ArchiveExpo SnackDiscord and ForumsNewsletter

Integrate in an existing library

Learn how to integrate Expo Modules API into an existing React Native library.


There are cases where you may want to integrate the Expo Modules API into an existing React Native library. For example, this may be useful to incrementally rewrite the library or to take advantage of iOS AppDelegate subscribers and Android Lifecycle listeners to automatically set up your library.

The following steps will set up your existing React Native library to access Expo Modules APIs.

Create the expo-module.config.json file at the root of your project and start from the empty object {} inside it. We will fill it in later to enable specific features. The presence of the module config is enough for Expo Autolinking to recognize it as an Expo module and automatically link your native code.

Add the expo-modules-core native dependency

Add expo-modules-core as a dependency in your podspec and build.gradle files.

*.podspec
# ...
Pod::Spec.new do |s|
  # ...
  s.dependency 'ExpoModulesCore'
end
build.gradle
// ...
dependencies {
  // ...
  implementation project(':expo-modules-core')
}

Add Expo packages to dependencies

Add expo package as a peer dependency in your package.json — we recommend using * as a version range so as not to cause any duplicated packages in user's node_modules folder. Your library also needs to depend on expo-modules-core but only as a dev dependency — it's already provided in the projects depending on your library by the expo package with the version of core that is compatible with the specific SDK used in the project.

package.json
{
  // ...
  "devDependencies": {
    "expo-modules-core": "^X.Y.Z"
  },
  "peerDependencies": {
    "expo": "*"
  },
  "peerDependenciesMeta": {
    "expo": {
      "optional": true
    }
  }
}

Create a native module

To use the Expo Modules API for native modules, you need to set up your library as an Expo module. Once complete, create Swift and Kotlin files from the templates below.

MyModule.swift
import ExpoModulesCore

public class MyModule: Module {
  public func definition() -> ModuleDefinition {
    // Definition components go here
  }
}
MyModule.kt
package my.module.package

import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition

class MyModule : Module() {
  override fun definition() = ModuleDefinition {
    // Definition components go here
  }
}

Then, add your classes to Android and/or iOS modules in the module config. Expo Autolinking will automatically link these classes as native modules in the user's project.

expo-module.config.json
{
  "ios": {
    "modules": ["MyModule"]
  },
  "android": {
    "modules": ["my.module.package.MyModule"]
  }
}

If you already have an example app in your workspace, ensure that the module is linked correctly.

  • On Android the native module class will be linked automatically before building, as part of the Gradle build task.
  • On iOS you need to run pod install to link the new class. These module classes can now be accessed from the JavaScript code using the requireNativeModule function from the expo-modules-core package. We recommend creating a separate file that exports the native module for simplicity.
MyModule.ts
import { requireNativeModule } from 'expo-modules-core';

export default requireNativeModule('MyModule');

Now that the class is set up and linked, you can start to implement its functionality. See the native module API reference page and links to examples from simple to moderately complex real-world modules for your reference to better understand how to use the API.