1--- 2title: 'Expo Modules API: Overview' 3sidebar_title: Overview 4description: An overview of the APIs and utilities provided by Expo to develop native modules. 5--- 6 7import { Grid01Icon, AndroidIcon, AppleIcon, Settings01Icon } from '@expo/styleguide-icons'; 8import { BoxLink } from '~/ui/components/BoxLink'; 9 10## What are Expo Modules 11 12Sometimes, installing an Expo package or a third-party library is not enough when looking to extend the capabilities of your app. In that scenario, you can write custom native code to tap into native platform APIs or use available Android or iOS dependencies. Luckily, Expo has first class support for this in the form of Expo Modules. 13 14Expo Modules allow you to write native code in a way that feels natural with minimal boilerplate that is also consistent on both platforms. 15It provides a set of APIs and utilities to improve the process of developing native modules for Expo and React Native and expand your app capabilities. 16 17<BoxLink 18 title="Native Modules" 19 description="Create native modules using Swift and Kotlin." 20 href="./module-api" 21 Icon={Grid01Icon} 22/> 23<BoxLink 24 title="Android Lifecycle Listeners" 25 description="Hook into Android Activity and Application lifecycle events." 26 href="./android-lifecycle-listeners" 27 Icon={AndroidIcon} 28/> 29<BoxLink 30 title="iOS AppDelegate Subscribers" 31 description="Respond to iOS AppDelegate events." 32 href="./appdelegate-subscribers" 33 Icon={AppleIcon} 34/> 35<BoxLink 36 title="expo-module.config.json" 37 description="Configure and opt in to features." 38 href="./module-config" 39 Icon={Settings01Icon} 40/> 41 42## Design considerations 43 44Our team needs to maintain a large set of libraries, and maintaining native modules over time and in a constantly changing environment is quite expensive. 45We found out that the existing React Native API for native modules is not scaling very well and is giving us some additional overhead on many levels, from onboarding new contributors (lack of good documentation) to writing a lot of boilerplate code. 46To make the maintenance easier and let the community iterate faster, we decided to create a module system that reduces the costs and technical debt to a minimum. 47 48### Why Swift and Kotlin? 49 50After several years of maintaining over 50 native modules in the Expo SDK, we have discovered that many issues were caused by unhandled null values or incorrect types. 51Modern language features can help developers avoid these bugs; for example, the lack of optional types combined with the dynamism of Objective-C made it tough to catch certain classes of bugs that would have been caught by the compiler in Swift. 52 53Another difficulty of writing React Native modules is context switching between the vastly different languages and paradigms for writing native modules on each platform. 54Due to the differences between these platforms, it cannot be avoided completely. We feel the need to have just one common API and documentation to simplify the development as much as possible and make it easier for a single developer to maintain a library on multiple platforms. 55 56This is one of the reasons why the Expo Modules ecosystem was designed from the ground up to be used with modern native languages: Swift and Kotlin. 57 58### Passing data between runtimes 59 60Another big pain point we have encountered is the validation of arguments passed from JavaScript to native functions. 61This is especially error-prone, time-consuming, and difficult to maintain when it comes to `NSDictionary` or `ReadableMap`, where the type of values is unknown in runtime, and each property needs to be validated separately by the developer. 62A valuable feature of the Expo native modules API is its full knowledge of the argument types the native function expects. It can pre-validate and convert the arguments for you! The dictionaries can be represented as native structs that we call [Records](./module-api/#records). 63Knowing the argument types, it is also possible to [automatically convert arguments](./module-api/#convertibles) to some platform-specific types (for example, `{ x: number, y: number }` or `[number, number]` can be translated to CoreGraphics's `CGPoint` for your convenience). 64 65### React Native New Architecture 66 67React Native version 0.68 introduced the [New Architecture](https://reactnative.dev/docs/the-new-architecture/landing-page), which offers developers new capabilities for building mobile apps. 68It consists of the new native modules system called [Turbo Modules](https://reactnative.dev/docs/the-new-architecture/pillars-turbomodules) and the new rendering system called [Fabric](https://reactnative.dev/architecture/fabric-renderer). 69Native libraries need to be adapted to take advantage of these new systems. For Fabric, it needs even more work as it doesn't provide any compatibility layer, which means that view managers written in the old way don't work with Fabric and the other way around — Fabric native components don't work with the old renderer. 70It basically implies that existing libraries have to provide support for both architectures for a while, increasing the technical debt. 71 72The new architecture is mostly written in C++, so you may end up writing some C++ code for your library as well. 73As we all, React Native developers, use high-level JavaScript on a daily basis, we are rather reluctant to write C++, which is on the opposite side of the spectrum. 74Moreover, including C++ code in the library has a negative impact on build times, especially on Android, and can be more difficult to debug. 75 76We took these into account when designing the Expo Modules API with the goal in mind to make it renderer-agnostic, so that the module doesn't need to know whether the app is run on the new architecture or not, significantly reducing the cost for library developers. 77 78## Next steps 79 80<BoxLink 81 title="Get Started" 82 description="Learn how to create a new Expo module or setup existing library as an Expo module." 83 href="./get-started" 84/> 85