Individual skill

expo-migrate-module

Migrate an existing Apple/Swift Expo native module from the Expo Modules API 1.0 definition DSL to the 2.0 macro API (sometimes called v2) while preserving its JavaScript and TypeScript contract. Use when converting or incrementally adopting @ExpoModule, @JS, @Event, @SharedObject, or @Record in an existing module. Do not use for creating a new module, general Expo SDK upgrades, or Android/Kotlin migrations.

plugins/expo-experiments/skills/expo-migrate-module/SKILL.md

Read pinned source

Source commit a9e5bd3fa00b4e61f632e43f85da73aee1942582

What was checked

Matches the observed repository HEAD
Yes
Scanner rules are current
Yes
Repository scan complete
No
Skill scan complete
No
Observed behavior
Network or broad shell
Last checked
Nov 9, 2026

These are observations at the recorded commit, not a guarantee of safety. Review the source before running it.

Install this skill

Choose an agent in your Stack or copy a command below. Commands fetch the pinned commit and copy only this skill directory. Existing destinations are refused. Copying a command does not install anything.

An install command is unavailable: current rules, complete repository and skill scans, an eligible behavior level and a permitted license are required.

Repository context

Repository stars (not skill ratings)
4,100
Repository last updated
Nov 6, 2026
License
MIT

Observed agent integration: No specific integration evidence. Standard SKILL.md installation does not imply verified compatibility.

Files and excerpt

File metadata and permitted, redacted excerpts come from the recorded scan. Source links are pinned to that commit.

Browse files
Read excerpt

# Migrate an Expo Module

Migrate the Swift side of an existing Expo module without changing its observable JS API. Treat the current JS/TypeScript surface and tests as the compatibility contract. Leave Kotlin on the 1.0 DSL unless the user explicitly expands the task.

## Prerequisite

Use `expo` `58.0.21` or newer. Earlier `58.0.x` releases lack tuple conversion and the `swift:check` and `swift:expand` commands of `expo-modules-cli`. Older ones also lack `lazy` `@JS` properties, `SharedRef<T>` subclasses in `@SharedObject`, static shared-object members, and `.withAsync`, and the oldest lack closure arguments and free-form `Any` return values. SDK 57 also lacks `.concurrent`, `@Union`, and module auto-discovery. Do not target either. Before editing, check the installed version (`npm ls expo`, or the lockfile). If it is older, stop and tell the user to upgrade first.

Check the example app's own dependencies too, not only the module root. The example app is the integration surface you build and launch in step 4, so it needs the same floor.

This is a floor, not a guarantee: the macro and core surface changed in almost every `58.0.x` patch release, so step 2 must still verify the installed source.

The macros are still **experimental and undocumented**: SDK 58 has no page about them in the Expo docs, and the API can still change under you. Say this to the user before a large migration, and prefer incremental mixed mode over converting a module wholesale.
Back to top