README.md
1<p>
2 <a href="https://docs.expo.dev/modules/">
3 <img
4 src="../../.github/resources/expo-modules-core.svg"
5 alt="expo-modules-core"
6 height="64" />
7 </a>
8</p>
9
10The core of Expo Modules architecture.
11
12# Installation in managed Expo projects
13
14For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects — it is likely to be included in an upcoming Expo SDK release.
15
16# Installation in bare React Native projects
17
18For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
19
20### Add the package to your npm dependencies
21
22```
23npm install expo-modules-core
24```
25
26### Configure for iOS
27
28Run `npx pod-install` after installing the npm package.
29
30### Configure for Android
31
32No additional set up necessary.
33
34# Importing native dependencies - autolinking
35
36Many React Native libraries come with platform-specific (native) code. This native code has to be linked into the project and, in some cases, configured further. These actions require some modifications to the native project files. One of the steps that has to be done with the native configuration is to enable the autolinking mechanism that takes care of including any supported module's native code into the project. The following configuration is required:
37
38### iOS
39
40> Caution! After you have made the following changes you will need to run `pod install` again.
41
42```ruby
43# Podfile
44
45require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
46require File.join(File.dirname(`node --print "require.resolve('expo-modules-core/package.json')"`), "cocoapods.rb")
47require File.join(File.dirname(`node --print "require.resolve('expo-modules-core/package.json')"`), "scripts/autolinking")
48
49# ...
50
51target "TargetName" do
52 use_unimodules!
53 config = use_native_modules!
54 use_react_native!(:path => config["reactNativePath"])
55
56 # ...
57end
58```
59
60### Android
61
62```groovy
63// app/build.gradle
64
65apply from: new File(["node", "--print", "require.resolve('expo-modules-core/package.json')"].execute(null, rootDir).text.trim(), "../gradle.groovy")
66apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../react.gradle")
67apply from: new File(["node", "--print", "require.resolve('expo-updates/package.json')"].execute(null, rootDir).text.trim(), "../scripts/create-manifest-android.gradle")
68
69// ...
70
71apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
72applyNativeModulesAppBuildGradle(project)
73```
74
75```groovy
76// settings.gradle
77
78apply from: new File(["node", "--print", "require.resolve('expo-modules-core/package.json')"].execute(null, rootDir).text.trim(), "../gradle.groovy");
79includeUnimodulesProjects()
80
81apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
82applyNativeModulesSettingsGradle(settings)
83```
84
85### Explanation
86
87The scripts that are referenced in Gradle and Cocoapods are usually found the related package inside the project's `node_modules` directory. In the case of monorepos (such as Yarn workspaces) the project directory may not contain `node_modules` at all; instead, the modules are likely to be located at the root of the repository. In order to ensure that both cases are supported, we take advantage of the Node dependency resolution strategy. We invoke a subprocess that spawns the simple JavaScript snippet that tries to locate the desired npm package containing the script we need.
88
89- On iOS, we use [`` ` ` `` (backtick)](https://stackoverflow.com/questions/3159945/running-command-line-commands-within-ruby-script) ([alternative reference](https://ruby-doc.org/core-3.0.2/Kernel.html#method-i-60)).
90- On Android, we use [String[]#execute](<http://docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/String[].html#execute()>) to obtain the results from the subprocess' stdout.
91
92The Node process that is spawned runs [`require.resolve`](https://nodejs.org/dist/latest-v14.x/docs/api/modules.html#modules_require_resolve_request_options) to obtain the path to a module's `package.json`(if you look for the module location using solely module name, you'll be given the path to the file pointed by the `main` attribute from the `package.json` and we need to know the location of the module's root directory). We then assemble the path to the desired script and execute it.
93
94You can read more about the scripts and libraries used in the examples above in their official READMEs.
95
96# Contributing
97
98Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing).
99