Expo Modules API là layer abstraction cao hơn TurboModule do Expo team viết. Cùng mục đích (gọi native từ JS) nhưng API gọn hơn nhiều, đặc biệt khi viết Swift/Kotlin idiomatic.
TurboModule (RN core):
- Spec TypeScript bắt buộc.
- Native code phải kế thừa class generated.
- Codegen step manual.
- Hỗ trợ Old + New Architecture.
Expo Modules:
- Định nghĩa module bằng DSL Swift/Kotlin:
// ios/MyModule/MyModule.swift
import ExpoModulesCore
public class MyModule: Module {
public func definition() -> ModuleDefinition {
Name("MyModule")
Function("greet") { (name: String) -> String in
"Hello, \(name)!"
}
AsyncFunction("fetchData") { (url: String) async throws -> [String: Any] in
// ...
}
}
}// android/src/main/java/expo/modules/mymodule/MyModule.kt
class MyModule : Module() {
override fun definition() = ModuleDefinition {
Name("MyModule")
Function("greet") { name: String -> "Hello, $name!" }
}
}JS side đơn giản:
import { requireNativeModule } from 'expo-modules-core'
const MyModule = requireNativeModule('MyModule')
MyModule.greet('World')Lợi điểm Expo Modules:
- Không cần spec TypeScript riêng (TS type inference từ DSL).
- Hỗ trợ event emitter, lifecycle, view component (cho Fabric) tích hợp sẵn.
- Unit test dễ hơn (mock DSL gọn).
- Expo team duy trì compat với RN versions.
Nhược:
- Phụ thuộc expo-modules-core ngay cả trong bare workflow (cần npx install-expo-modules).
- Ít control low-level so với TurboModule.
Khi nào chọn:
- Đang dùng Expo (managed hoặc bare): mặc định Expo Modules.
- Lib RN community thuần, không Expo: TurboModule.
- Performance siêu critical (audio DSP, ML): TurboModule + JSI custom (kiểm soát layer thấp hơn).