# ...
Pod::Spec.new do |s|
  # ...
  s.dependency 'ExpoModulesCore'
end
```
Step 2: 
## Add Expo packages to dependencies
Add `expo` package as a peer dependency in your **package.json** &mdash; we recommend using `*` as a version range so as not to cause any duplicated packages in user's **node_modules** directory.
Your library also needs to depend on `expo-modules-core` but only as a dev dependency &mdash; it's already provided in the projects depending on your library by the `expo` package with the version of core that is compatible with the specific SDK used in the project.
```json package.json
{
  "devDependencies": {
    "expo-modules-core": "^X.Y.Z"
  },
  "peerDependencies": {
    "expo": "*"
  },
  "peerDependenciesMeta": {
    "expo": {
      "optional": true
    }
  }
}
```
Step 3: 
## Create a native module
Create Kotlin and Swift files from the templates below:
```kotlin
package my.module.package
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
class MyModule : Module() {
  override fun definition() = ModuleDefinition {
    // Definition components go here
  }
}
```
```swift
import ExpoModulesCore
public class MyModule: Module {
  public func definition() -> ModuleDefinition {
    // Definition components go here
  }
}
```
Then, add your classes to Android and/or iOS `modules` in the [**expo-module.config.json**](/modules/module-config/) file. Expo Autolinking will automatically link these classes as native modules in the user's project.
```json expo-module.config.json
{
  "ios": {
    "modules": ["MyModule"]
  },
  "android": {
    "modules": ["my.module.package.MyModule"]
  }
}
```
If you already have an example app in your workspace, ensure that the module is linked correctly.
- **On Android** the native module class will be linked automatically before building, as part of the Gradle build task.
- **On iOS** you need to run `pod install` to link the new class.
These module classes are now accessible from the JavaScript code using the `requireNativeModule` function from the `expo-modules-core` package. We recommend creating a separate file that exports the native module for simplicity.
```ts MyModule.ts
import { requireNativeModule } from 'expo-modules-core';
export default requireNativeModule('MyModule');
```
Now that the class is set up and linked, you can start to implement its functionality. See the [native module API](/modules/module-api/) reference page and links to [examples](/modules/module-api/#examples) from simple to moderately complex real-world modules to understand how to use the API.


## Additional platform support

Learn how to add support for macOS and tvOS platforms.

Expo Modules API provides first-class support for Android and iOS. However, since all Apple platforms are based on the same foundation and use the same programming language, targeting other [Out-of-Tree platforms](https://reactnative.dev/docs/out-of-tree-platforms) in the Expo module is possible.
Currently, only **macOS** and **tvOS** platforms are supported. This guide will walk you through adding support for these platforms.
Step 1: 
## Use the `"apple"` platform in `expo-module.config.json`
To provide seamless support for other Apple platforms, Expo SDK introduced a universal `"apple"` platform to instruct the [autolinking](/modules/autolinking/) that the module may support any of the Apple platform and whether to link the module in the specific CocoaPods target is moved off to the podspec. If you have used `"ios"` before, you can safely replace it:
```diff
diff --git a/expo-module.config.json b/expo-module.config.json
index 0000000..1111111 100644
--- a/expo-module.config.json
+++ b/expo-module.config.json
@@ -1,5 +1,5 @@
-  "platforms": ["ios"],
-  "ios": {
-    "modules": ["MyModule"]
-  }
+  "platforms": ["apple"],
+  "apple": {
+    "modules": ["MyModule"]
+  }
 }
```
Step 2: 
## Update the podspec to declare support for other platforms
The module's podspec needs to be updated with a list of the supported platforms. Otherwise, CocoaPods would fail to install the pod on targets for the other platforms. As mentioned in the first step, this part of the spec is the source of truth for autolinking when the module is configured with a universal `"apple"` platform.
```diff
diff --git a/YourModule.podspec b/YourModule.podspec
index 0000000..1111111 100644
--- a/YourModule.podspec
+++ b/YourModule.podspec
@@ -1,5 +1,5 @@
- s.platform       = :ios, '13.4'
+ s.platforms = {
+   :ios => '13.4',
+   :tvos => '13.4',
+   :osx => '10.15'
+ }
```
Any changes in the podspec require running `pod install` to have an effect.
Step 3: 
## Set up `react-native-macos` or `react-native-tvos` in the app
If you are writing a local module and your app is already set up, you can skip this step. Otherwise, you will need to set up your app or the example app if you are writing a standalone (non-local) module.
- **For macOS**: follow the official [Install React Native for macOS](https://microsoft.github.io/react-native-windows/docs/rnm-getting-started#install-the-macos-extension) guide from `react-native-macos` documentation.
- **For tvOS**: follow the instructions in the [`react-native-tvos`](https://github.com/react-native-tvos/react-native-tvos) repository. If you are building an Expo app, you should also follow the instructions in the [Build Expo apps for TV guide](/guides/building-for-tv/).
Step 4: 
## Review the code for using APIs not supported on these platforms
Platform APIs may differ between Apple platforms. The most noticeable difference comes from relying on different UI frameworks &mdash;`UIKit` on iOS/tvOS and `AppKit` on macOS.
Both `react-native-macos` and `expo-modules-core` provide aliases and polyfills to reference`UIKit` classes on macOS target (for example, `UIView` is an alias to `NSView`, `UIApplication` is an alias to `NSApplication`), but it's usually not enough for iOS-first libraries to support other platforms out of the box. You may need to write conditionally compiled code that uses different implementations depending on the platform.
To do this, use Swift compiler directives with the `os` condition, which includes a given piece of code when our app is being built for a specific platform. In combination with the `#if` and `#else` directives, lets you set up platform-specific branches within the cross-platform code.
```swift
#if os(iOS)
  // iOS implementation
#elseif os(macOS)
  // macOS implementation
#elseif os(tvOS)
  // tvOS implementation
#endif
```
Your module is now ready to be used on Out-of-Tree platform.