xref: /expo/docs/pages/modules/overview.mdx (revision a91cbdc6)
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