expo-module
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWriting Expo Modules
编写Expo模块
Complete reference for building native modules and views using the Expo Modules API. Covers Swift (iOS), Kotlin (Android), and TypeScript.
使用Expo Modules API构建原生模块与视图的完整参考指南,涵盖Swift(iOS)、Kotlin(Android)和TypeScript技术栈。
When to Use
适用场景
- Creating a new Expo native module or native view
- Adding native functionality (camera, sensors, system APIs) to an Expo app
- Wrapping platform SDKs for React Native consumption
- Building config plugins that modify native project files
- Adding Android, Apple, or web support to an existing Expo module
- Editing , config plugins, or lifecycle hooks
expo-module.config.json
To migrate an existing Swift module from the definition DSL to the Expo Modules API 2.0 macros (, , ), use the skill (from the plugin) instead.
@ExpoModule@JS@Eventexpo-migrate-moduleexpo-experiments- 创建新的Expo原生模块或原生视图
- 为Expo应用添加原生功能(相机、传感器、系统API)
- 封装平台SDK以供React Native调用
- 构建可修改原生项目文件的config plugins
- 为现有Expo模块添加Android、Apple或Web支持
- 编辑、config plugins或生命周期钩子
expo-module.config.json
若要将现有Swift模块从定义DSL迁移至Expo Modules API 2.0宏(、、),请使用插件中的工具。
@ExpoModule@JS@Eventexpo-experimentsexpo-migrate-moduleReferences
参考资源
Consult these resources as needed:
references/
create-expo-module.md Scaffolding and add-platform-support workflow, defaults, and quirks
native-module.md Module definition DSL: Name, Function, AsyncFunction, Property, Constant, Events, type system, shared objects
native-view.md Native view components: View, Prop, EventDispatcher, view lifecycle, ref-based functions
lifecycle.md Lifecycle hooks: module, iOS app/AppDelegate, Android activity/application listeners
config-plugin.md Config plugins: modifying Info.plist, AndroidManifest.xml, reading values in native code
module-config.md expo-module.config.json fields, file placement, and autolinking behavior按需查阅以下资源:
references/
create-expo-module.md 脚手架与跨平台支持工作流、默认配置及注意事项
native-module.md 模块定义DSL:名称、函数、异步函数、属性、常量、事件、类型系统、共享对象
native-view.md 原生视图组件:视图、属性、事件分发器、视图生命周期、基于引用的函数
lifecycle.md 生命周期钩子:模块、iOS应用/AppDelegate、Android Activity/应用监听器
config-plugin.md 配置插件:修改Info.plist、AndroidManifest.xml、在原生代码中读取值
module-config.md expo-module.config.json字段、文件位置及自动链接行为Quick Start
快速开始
Prefer over manually creating native module files and directories. In practice, the best path is usually to create the scaffold first and then build on top of it. The scaffold sets up the expected layout, , podspec or Gradle files, TypeScript bindings, and the standalone example app flow.
create-expo-moduleexpo-module.config.jsonIf an existing Expo module only needs another platform, use instead of manually copying native directories.
create-expo-module add-platform-supportSee references/create-expo-module.md before scaffolding or extending a module. It covers:
- local vs standalone modules
- ,
--platform,--features,--barrel, and non-interactive mode--package-manager expo.autolinking.nativeModulesDir- behavior and quirks
add-platform-support
优先使用工具,而非手动创建原生模块文件和目录。实际开发中,最佳路径通常是先搭建脚手架,再基于此进行开发。脚手架会设置预期的目录结构、、podspec或Gradle文件、TypeScript绑定以及独立示例应用流程。
create-expo-moduleexpo-module.config.json若现有Expo模块仅需新增平台支持,请使用命令,而非手动复制原生目录。
create-expo-module add-platform-support搭建或扩展模块前,请查阅references/create-expo-module.md,其中涵盖:
- 本地模块与独立模块的区别
- 、
--platform、--features、--barrel参数及非交互模式--package-manager - 配置
expo.autolinking.nativeModulesDir - 命令的行为及注意事项
add-platform-support
Recommended Workflow
推荐工作流
- Choose the scaffold type first:
- Local module for one app
- Standalone module for reuse, monorepos, or publishing
- Determine native features that you will need.
expo-module- Based on the user's instructions determine which feature scaffolding will be useful.
- Available features: ,
Constant,Function,AsyncFunction,Event,View,ViewEventSharedObject
- Scaffold deliberately:
- pass an explicit slug or path
- choose intentionally instead of relying on defaults
--platform - use to choose code samples which you will modify in the next step to match the real implementation.
--features
- Replace generated example code with the real implementation.
- If you add a new platform later, prefer over manual file copying.
add-platform-support
- 首先选择脚手架类型:
- 本地模块:仅用于单个应用
- 独立模块:用于复用、单仓项目或发布
- 确定所需的原生功能:
expo-module- 根据用户需求判断哪些功能脚手架有用
- 可用功能:、
Constant、Function、AsyncFunction、Event、View、ViewEventSharedObject
- 谨慎搭建脚手架:
- 传入明确的slug或路径
- 主动选择参数,而非依赖默认值
--platform - 使用选择代码示例,后续将其修改为实际实现
--features
- 将生成的示例代码替换为实际实现
- 若后续新增平台,优先使用命令,而非手动复制文件
add-platform-support
Practical Scaffolding Rules
实用脚手架规则
- Feature examples are opt-in. A newly scaffolded module may be minimal if no features were selected.
- implies
ViewEvent.View - Local modules do not generate an barrel by default. Use
index.tsonly if you want one.--barrel - In non-interactive local scaffolding, pass the positional slug or path explicitly. changes the native class name, not the folder name.
--name - Local modules live in when configured, otherwise in
expo.autolinking.nativeModulesDir.modules/ - Standalone modules have their own package metadata, scripts, and usually an example app. Local modules use the host app's tooling instead.
- 功能示例为可选。若未选择任何功能,新搭建的模块可能仅包含基础结构
- 依赖
ViewEvent功能View - 本地模块默认不会生成桶文件。仅当需要时使用
index.ts参数--barrel - 在非交互式本地脚手架中,需显式传入位置参数slug或路径。参数仅修改原生类名,不修改文件夹名称
--name - 配置后,本地模块位于目录,否则位于
expo.autolinking.nativeModulesDir目录modules/ - 独立模块拥有自己的包元数据、脚本,通常包含示例应用。本地模块则使用宿主应用的工具链
Core File Shapes
核心文件结构
The Swift and Kotlin DSL share the same structure. Swift is usually the clearest primary example; consult the references for feature-specific details.
Swift和Kotlin DSL共享相同的结构。Swift通常是最清晰的主要示例;如需特定功能的详细信息,请查阅参考资源。
Module Structure Reference
模块结构参考
The Swift and Kotlin DSL share the same structure. Both platforms are shown here for reference — in other reference files, Swift is shown as the primary language unless the Kotlin pattern meaningfully differs.
Swift (iOS):
swift
import ExpoModulesCore
public class MyModule: Module {
public func definition() -> ModuleDefinition {
Name("MyModule")
Function("hello") { (name: String) -> String in
return "Hello \(name)!"
}
}
}Kotlin (Android):
kotlin
package expo.modules.mymodule
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
class MyModule : Module() {
override fun definition() = ModuleDefinition {
Name("MyModule")
Function("hello") { name: String ->
"Hello $name!"
}
}
}TypeScript:
typescript
import { requireNativeModule } from "expo";
const MyModule = requireNativeModule("MyModule");
export function hello(name: string): string {
return MyModule.hello(name);
}Swift和Kotlin DSL共享相同的结构。此处展示两个平台的示例供参考——在其他参考文件中,除非Kotlin模式有显著差异,否则将Swift作为主要语言展示。
Swift (iOS):
swift
import ExpoModulesCore
public class MyModule: Module {
public func definition() -> ModuleDefinition {
Name("MyModule")
Function("hello") { (name: String) -> String in
return "Hello \(name)!"
}
}
}Kotlin (Android):
kotlin
package expo.modules.mymodule
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
class MyModule : Module() {
override fun definition() = ModuleDefinition {
Name("MyModule")
Function("hello") { name: String ->
"Hello $name!"
}
}
}TypeScript:
typescript
import { requireNativeModule } from "expo";
const MyModule = requireNativeModule("MyModule");
export function hello(name: string): string {
return MyModule.hello(name);
}expo-module.config.json
expo-module.config.json
json
{
"platforms": ["android", "apple"],
"apple": {
"modules": ["MyModule"]
},
"android": {
"modules": ["expo.modules.mymodule.MyModule"]
}
}Note: iOS uses just the class name; Android uses the fully-qualified class name (package + class). See for all fields.
references/module-config.mdjson
{
"platforms": ["android", "apple"],
"apple": {
"modules": ["MyModule"]
},
"android": {
"modules": ["expo.modules.mymodule.MyModule"]
}
}注意:iOS仅使用类名;Android使用全限定类名(包名+类名)。所有字段请查阅。
references/module-config.mdSubmitting Feedback
提交反馈
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
bash
npx --yes submit-expo-feedback@latest --category skills --subject "expo-module" "<actionable feedback>"Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
If an AI agent repeatedly failed or the user had to take over an Expo task, load the expo-skill-feedback skill and follow its eval-candidate flow instead of reusing the command above.
如果您在使用本指南时遇到错误、误导性或过时信息,请反馈给Expo以帮助改进:
bash
npx --yes submit-expo-feedback@latest --category skills --subject "expo-module" "<可操作的反馈内容>"仅当您有具体且可操作的内容时提交反馈,并尽可能包含相关上下文。
如果AI代理多次执行失败,或用户需要接管Expo任务,请加载expo-skill-feedback工具并遵循其评估流程,而非重复使用上述命令。