Currently, the popular React Native framework is Expo, which provides the Expo Modules API for us to quickly develop a Native component or module.
This article will briefly introduce how to initialize and write a simple Native component in Expo ~52 within the current project.
Preparation#
Before starting, make sure you have created an Expo project.
Then, create an Expo Module using the following command.
npx create-expo-module@latest --local
Follow the prompts to create a Module. It is located under modules/<name> and contains the following files.
.
├── android
│ ├── build.gradle
│ └── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── expo
│ └── modules
│ └── testmodule
│ ├── TestModule.kt
│ └── TestModuleView.kt
├── expo-module.config.json
├── index.ts
├── ios
│ ├── TestModule.podspec
│ ├── TestModule.swift
│ └── TestModuleView.swift
└── src
├── TestModule.ts
├── TestModule.types.ts
├── TestModule.web.ts
├── TestModuleView.tsx
└── TestModuleView.web.tsx
10 directories, 14 files
Among them, the android and ios directories are the entry points for writing native code.
Integrating into an Existing Project#
Now we need to apply this module to the current app.
Edit package.json to add this field:
"expo": {
"autolinking": {
"nativeModulesDir": "./modules"
}
},
Then, run npm run expo prebuild --clean to refresh the iOS and Android projects.
After the native dependencies are installed, we open the xcworkspace file using Xcode.

Writing a Simple Module#
An official example module already exists in the initial template. We can also try writing a simple component ourselves. Below is an example written for the iOS platform using Swift UI.
Find our module location as shown in the image.

Create a new internal module and organize the files as follows:
../ListView
├── ListView.swift
└── ListViewModule.swift

In ListView.swift, write the following code for a simple SwiftUI List:
import SwiftUI
struct ListView: View {
var body: some View {
List {
ForEach(1...10, id: \.self) { index in
Text("\(index)")
}
}
}
}
#Preview {
ListView()
}
Then define the Expo Module by editing ListViewModule.swift
import ExpoModulesCore
import SwiftUI
class ListViewProps: ExpoSwiftUI.ViewProps {
}
fileprivate struct ListViewExpoView: ExpoSwiftUI.View {
@EnvironmentObject var props: ListViewProps
var body: some View {
ListView()
}
}
public class ListViewModule: Module {
public func definition() -> ModuleDefinition {
Name("ListView") // Identifier used for calling requireNativeView later
View(ListViewExpoView.self) // Use ListViewExpoView
}
}
At this point, the native side is complete. Next, modify expo-module.config.json
Add the newly added ListViewModule.
{
"platforms": [
"apple",
"android",
"web"
],
"apple": {
"modules": [
"TestModule",
"ListViewModule" // Added
]
},
"android": {
"modules": [
"expo.modules.testmodule.TestModule"
]
}
}
Since we haven't implemented Android, we won't write it here. Then execute npm expo prebuild.
Using Native Components in React Native#
After the above steps, we can use it in React Native like this.
import { requireNativeView } from 'expo'
import type { ViewProps } from 'react-native'
interface ListViewProps extends ViewProps {}
const ListView = requireNativeView<ListViewProps>('ListView') // Use the Name defined above
export default function HomeScreen() {
return <ListView style={{ flex: 1 }} />
}
Then start the project in Xcode while also starting the metro dev server.
Through Xcode View Hierarchy, we can see that the NativeView has rendered correctly.

This article is synchronized and updated to xLog by Mix Space. The original link is https://innei.in/posts/tech/use-native-components-in-expo