expo-migrate-module

Migrate Swift Expo native modules from the 1.0 definition DSL to the 2.0 macro API.

Updated Sep 8, 2026
One-click install
npx skills add https://github.com/bmiit145/leadBee --skill expo-migrate-module-bmiit145
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: expo-migrate-module
Source: https://github.com/bmiit145/leadBee/tree/main/mobile/.agents/skills/expo-migrate-module
Command: npx skills add https://github.com/bmiit145/leadBee --skill expo-migrate-module-bmiit145

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Migrating an existing Apple/Swift Expo native module from the Expo Modules API 1.0 definition DSL to the 2.0 macro API is risky: macro support varies across expo-modules-core versions, async threading semantics changed architecturally, and a verbatim rewrite can silently break the JavaScript contract. This Skill provides a verified, incremental migration workflow that preserves the module's observable JS/TypeScript API. ## Core Features & Use Cases - Contract-first migration: Inventories every exported member (functions, properties, events, records, shared objects, lifecycle hooks) and treats the existing JS/TS surface and tests as the compatibility contract. - Compatibility verification: Checks the checked-out expo-modules-core source for actual macro and runtime support before migrating each member, instead of trusting SDK version numbers. - Mixed-mode fallback: Classifies members as Migrate, Keep in DSL, or Blocked, and supports incremental co-existence of @ExpoModule macros with a remaining 1.0 definition() block. - Use Case: You maintain an Expo module with AsyncFunction, Events, and Record definitions on SDK 57. Use this Skill to convert them to @JS, @Event, and @Record macros while preserving event wire names, record requiredness, and off-JS-thread execution for blocking work. ## Quick Start Use the expo-migrate-module skill to migrate this Expo module's Swift implementation from the 1.0 definition DSL to the 2.0 macro API without changing its JavaScript contract.

Frequently Asked Questions about expo-migrate-module

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I migrate an Expo module from the 1.0 DSL to the 2.0 macro API?▼

Inventory every exported member first, then verify macro and core support in the checked-out expo-modules-core before editing. Migrate one semantic group at a time (naming, functions, properties, events, shared objects, records), keeping unsupported members in the 1.0 definition() block as mixed mode.

What Expo SDK version is required for the 2.0 macro API?▼

Use expo 57.0.21 or newer; earlier 57.x versions compile the macros but lack many 2.0 features. The macros are experimental in SDK 57 with the official beta in SDK 58, so verify the checked-out expo-modules-core source rather than trusting version numbers.

Does the 2.0 macro API change async function threading behavior?▼

Yes. A 1.0 AsyncFunction body runs off the JS thread, while a 2.0 async @JS member starts on the JS thread and leaves only at the first await. A body that never awaits blocks the JS thread; fix it with @JS(.concurrent) or restructure onto Swift Concurrency.

Can I migrate only part of an Expo module to the 2.0 macros?▼

Yes, mixed mode is supported: @ExpoModule can coexist with a non-empty definition() block when the core supports merging both surfaces. Keep unsupported items like views, static shared-object members, or queue-pinned functions in the DSL until core support lands.

Why does my migrated Expo module build but not load at runtime?▼

The expo-module.config.json entries under apple.modules are bare Swift class names with no compile-time link. Renaming a class during migration silently detaches the module, so verify the config still names every module class and that classes remain public or open.

When should I not use this migration approach?▼

Do not use it for creating a new module, general Expo SDK upgrades, or Android/Kotlin migrations, which stay on the 1.0 DSL. Also avoid it when the checked-out core lacks required runtime hooks, since macro expansion alone does not guarantee linking or runtime invocation.