<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/an-early-look-at-expo-modules-2-0-expo-blog-fqyfapxkh" -->

---
title: An early look at Expo Modules 2.0 — Expo blog | daily.dev
description: Expo Modules 2.0 replaces the 1.0 DSL (built on Swift result builders) with plain annotated Swift and Kotlin classes: a module becomes a class with @JS-marked...
canonical: https://daily.dev/posts/an-early-look-at-expo-modules-2-0-expo-blog-fqyfapxkh
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: An early look at Expo Modules 2.0 — Expo blog | daily.dev
og:description: Expo Modules 2.0 replaces the 1.0 DSL (built on Swift result builders) with plain annotated Swift and Kotlin classes: a module becomes a class with @JS-marked...
og:url: https://daily.dev/posts/an-early-look-at-expo-modules-2-0-expo-blog-fqyfapxkh
og:image: https://api.daily.dev/og/posts/FqyFApxKH.png
og:image:alt: An early look at Expo Modules 2.0 — Expo blog
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# An early look at Expo Modules 2.0 — Expo blog

**[Expo Blog](https://daily.dev/sources/expo-blog)** · 11 min read · 1 upvotes · 0 comments

## Summary

Expo Modules 2.0 replaces the 1.0 DSL (built on Swift result builders) with plain annotated Swift and Kotlin classes: a module becomes a class with @JS-marked methods and properties, no definition() function or Name(...) boilerplate. Records, shared objects, and events follow the same pattern using @Record, @SharedObject, and @Event macros. The core macros already ship in SDK 57 for iOS (experimental, undocumented), with an official beta landing in SDK 58 alongside Android support. Because the @JS macro reads Swift function signatures at build time instead of relying on runtime reflection, synchronous calls are 2.5 to 5.6x faster than the 1.0 API on the same SDK; SDK 56's removal of the Objective-C++ layer already made calls 1.5-2x faster than SDK 55. An expo-migrate-module coding-agent skill can automatically convert existing modules from 1.0 to 2.0 incrementally, and generated TypeScript declarations from native code are planned next.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://expo.dev/blog/an-early-look-at-expo-modules-2-0>

## Questions this post answers

### What is Expo Modules 2.0 and how is it different from the 1.0 API?

Expo Modules 2.0 lets you write a native module as an ordinary annotated Swift or Kotlin class instead of using the 1.0 result-builder DSL. Methods get a @JS annotation, properties are plain Swift vars, and there's no definition() function or Name(...) boilerplate. It ships experimentally on iOS in SDK 57, with an official beta for SDK 58 and Android support in progress.

_Track native module API changes like this on daily.dev before you rebuild your Expo integration._

### How much faster are Expo Modules 2.0 calls compared to Expo Modules 1.0?

Synchronous calls using the @JS macro are 2.5 to 5.6 times faster than the 1.0 API on the same SDK, because the macro reads Swift function signatures at build time instead of relying on runtime reflection with allocated, reference-counted containers. Async calls are close between the two APIs since both share the same promise machinery, measured on an iPhone 16 Pro running iOS 27.

_Developers comparing native module performance trade-offs can follow benchmarks like this on daily.dev._

### Can I migrate an existing Expo module from 1.0 to 2.0 automatically?

Yes, the expo-migrate-module skill migrates a module's Swift side from 1.0 to 2.0 while keeping the JavaScript API unchanged, and it can be run interactively with a coding agent via 'npx skills@latest use expo/skills@expo-migrate-module --agent claude-code'. Anything it cannot migrate is left in the 1.0 definition() and listed in its report, and the two APIs can coexist during incremental migration.

_Anyone planning a phased native module migration can follow tooling updates like this on daily.dev._

---

Tags: [#swift](https://daily.dev/tags/swift), [#react-native](https://daily.dev/tags/react-native), [#kotlin](https://daily.dev/tags/kotlin)

[View this post on daily.dev](https://daily.dev/posts/an-early-look-at-expo-modules-2-0-expo-blog-fqyfapxkh)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"An early look at Expo Modules 2.0 — Expo blog","url":"https://daily.dev/posts/an-early-look-at-expo-modules-2-0-expo-blog-fqyfapxkh","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/an-early-look-at-expo-modules-2-0-expo-blog-fqyfapxkh"},"datePublished":"2026-09-08T16:31:46.311Z","dateModified":"2026-09-08T16:32:13.387Z","description":"Expo Modules 2.0 replaces the 1.0 DSL (built on Swift result builders) with plain annotated Swift and Kotlin classes: a module becomes a class with @JS-marked...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/6a7290cedf3e9b65dd00b63729d3ec78?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/6a7290cedf3e9b65dd00b63729d3ec78?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Expo Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Expo Blog","logo":"https://media.daily.dev/image/upload/s--E7LK6L3y--/f_auto,q_auto/v1774179051/logos/expo-blog?_a=BAMAMiWQ0","url":"https://daily.dev/sources/expo-blog"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/an-early-look-at-expo-modules-2-0-expo-blog-fqyfapxkh","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"swift,react-native,kotlin","timeRequired":"PT11M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Expo Blog","item":"https://daily.dev/sources/expo-blog"},{"@type":"ListItem","position":3,"name":"An early look at Expo Modules 2.0 — Expo blog"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/an-early-look-at-expo-modules-2-0-expo-blog-fqyfapxkh#faq","mainEntity":[{"@type":"Question","name":"What is Expo Modules 2.0 and how is it different from the 1.0 API?","acceptedAnswer":{"@type":"Answer","text":"Expo Modules 2.0 lets you write a native module as an ordinary annotated Swift or Kotlin class instead of using the 1.0 result-builder DSL. Methods get a @JS annotation, properties are plain Swift vars, and there's no definition() function or Name(...) boilerplate. It ships experimentally on iOS in SDK 57, with an official beta for SDK 58 and Android support in progress. Track native module API changes like this on daily.dev before you rebuild your Expo integration."}},{"@type":"Question","name":"How much faster are Expo Modules 2.0 calls compared to Expo Modules 1.0?","acceptedAnswer":{"@type":"Answer","text":"Synchronous calls using the @JS macro are 2.5 to 5.6 times faster than the 1.0 API on the same SDK, because the macro reads Swift function signatures at build time instead of relying on runtime reflection with allocated, reference-counted containers. Async calls are close between the two APIs since both share the same promise machinery, measured on an iPhone 16 Pro running iOS 27. Developers comparing native module performance trade-offs can follow benchmarks like this on daily.dev."}},{"@type":"Question","name":"Can I migrate an existing Expo module from 1.0 to 2.0 automatically?","acceptedAnswer":{"@type":"Answer","text":"Yes, the expo-migrate-module skill migrates a module's Swift side from 1.0 to 2.0 while keeping the JavaScript API unchanged, and it can be run interactively with a coding agent via 'npx skills@latest use expo/skills@expo-migrate-module --agent claude-code'. Anything it cannot migrate is left in the 1.0 definition() and listed in its report, and the two APIs can coexist during incremental migration. Anyone planning a phased native module migration can follow tooling updates like this on daily.dev."}}]}
```

