xref: /expo/docs/pages/modules/get-started.mdx (revision fc13df4e)
1---
2title: Get Started
3---
4
5import { CodeBlocksTable } from '~/components/plugins/CodeBlocksTable';
6import { Terminal } from '~/ui/components/Snippet';
7
8## Create a new module
9
10To create a new Expo module from scratch, run the `create-expo-module` script as shown below. The script will ask you a few questions and then generate the native Expo module along with the example app for iOS and Android that uses your new module.
11
12<Terminal cmd={[`$ npx create-expo-module`]} />
13
14## Set up a library as an Expo module
15
16You can use the Expo Modules API in existing React Native libraries.
17The following steps will set up your existing React Native library to access Expo Modules APIs.
18
19Create the [**expo-module.config.json**](./module-config.mdx) 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.
20The presence of the module config is enough for [Expo Autolinking](/workflow/glossary-of-terms/#expo-autolinking) to recognize it as an Expo module and automatically link your native code.
21
22### Add the `expo-modules-core` native dependency
23
24Add `expo-modules-core` as a dependency in your podspec and **build.gradle** files.<br/>
25
26<CodeBlocksTable tabs={["*.podspec", "build.gradle"]}>
27
28```ruby
29# ...
30Pod::Spec.new do |s|
31  # ...
32  s.dependency 'ExpoModulesCore'
33end
34```
35
36```groovy
37// ...
38dependencies {
39  // ...
40  implementation project(':expo-modules-core')
41}
42```
43
44</CodeBlocksTable>
45
46### Add Expo packages to dependencies
47
48Add `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.<br/>
49
50```json package.json
51{
52  // ...
53  "devDependencies": {
54    "expo-modules-core": "^X.Y.Z"
55  },
56  "peerDependencies": {
57    "expo": "*"
58  }
59}
60```
61
62## Create a native module
63
64To use the Expo Modules API for native modules, you need to [set up your library as an Expo module](#set-up-a-library-as-an-expo-module). Once complete, create Swift and Kotlin files from the templates below.
65
66<CodeBlocksTable tabs={["MyModule.swift", "MyModule.kt"]}>
67
68```swift
69import ExpoModulesCore
70
71public class MyModule: Module {
72  public func definition() -> ModuleDefinition {
73    // Definition components go here
74  }
75}
76```
77
78```kotlin
79package my.module.package
80
81import expo.modules.kotlin.modules.Module
82import expo.modules.kotlin.modules.ModuleDefinition
83
84class MyModule : Module() {
85  override fun definition() = ModuleDefinition {
86    // Definition components go here
87  }
88}
89```
90
91</CodeBlocksTable>
92
93Then, add your classes to Android and/or iOS `modules` in the [module config](./module-config.mdx). Expo Autolinking will automatically link these classes as native modules in the user's project.
94
95```json expo-module.config.json
96{
97  "ios": {
98    "modules": ["MyModule"]
99  },
100  "android": {
101    "modules": ["my.module.package.MyModule"]
102  }
103}
104```
105
106If you already have an example app in your workspace, ensure that the module is linked correctly.
107
108- **On Android** the native module class will be linked automatically before building, as part of the Gradle build task.
109- **On iOS** you need to run `pod install` to link the new class.
110  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.
111
112```ts MyModule.ts
113import { requireNativeModule } from 'expo-modules-core';
114
115export default requireNativeModule('MyModule');
116```
117
118Now that the class is set up and linked, you can start to implement its functionality. See the [native module API](./module-api.mdx) reference page and links to [examples](./module-api.mdx#examples) from simple to moderately complex real-world modules for your reference to better understand how to use the API.
119