1
Set up your React Native project (either CLI or Expo) (Prerequisites).
2
Install the Ditto package into your project. (Installing the Ditto
SDK)
3
Install the project dependencies. (Installing
Dependencies)
4
If using Expo Dev Builds, configure Ditto with the Expo plugin. If using React
Native CLI, configure iOS and Android permissions. (Expo Setup
or Configuring Permissions)
5
If using React Native CLI (Android), handle runtime permissions. (Handling
Permissions)
6
Set up authentication. (Setting Up
Authentication)
7
Specify how Ditto should handle sync. (Creating a New Instance of
Ditto)
8
Configure peer-to-peer transport options. (Setting Transport
Configurations)
9
Add Sync Subscription logic. (Constructing Sync Subscription Logic)
10
Start the sync process. (Starting the Sync
Process)
11
(Optional) Monitor remote peers. (Setting Up Presence)
12
(Optional) Set logs to debug. (Setting the Logs to Debug
Level)
13
(Optional) Declare a foreground service (Android Only). (Declaring a
Foreground Service)
Prerequisites
First, set up your environment and initialize your React Native project. For instructions, see React Native’s official documentation on Get Started with React Native.To verify that you’ve set up your environment correctly, install and run the
React Native CLI doctor. For more information, see the official blog post:Meet Doctor, a new React Native command
Installing the Ditto SDK
From a terminal, navigate to the folder containing your React Native project, and then, using your preferred package manager, run the Ditto package:Installing Dependencies
From the root of your project, install project dependencies based on thepackage.json
file:
If you’re using Expo, install these additional dependencies:
Expo Setup
iOS and Android only - Expo does not support macOS. For macOS development, use React Native CLI.
Expo Go is not compatible with this SDK because it does not support custom
native modules. You will need to use Expo Dev
Builds
(version 50+).
app.json
or app.config.js
, depending on your project’s configuration:
Additional Requirements for Older Expo Projects
For older projects that have not yet migrated to:-
Android
minSdkVersion
24 - Kotlin version 1.9.0
- iOS Deployment Target 14.0
expo-build-properties
to ensure compatibility. Add the following to app.json
or app.config.js
:
Additional Parameters (iOS only)
The Ditto Expo plugin allows additional iOS prompts configurations, which are applied in the following order of priority:- Explicitly defined parameters in
app.json
orapp.config.js
. - If no parameters are set, it falls back to the iOS native project’s
Info.plist
. - If no values are found, Ditto uses its default values.
Configuring Permissions (non-Expo only)
Once you’ve added dependencies, set up the prerequisites to enable Ditto Transports for iOS, Android, and macOS.iOS and macOS
From Xcode, enable Bluetooth LE and local network services in your app:1
Install pods and make sure you use a compatible minimum deployment target.For iOS projects, from the For macOS projects, from the Be sure to reinstall Pods afterward:
ios/Podfile
file in your project:macos/Podfile
file in your project:Tip: No version changes are needed for RN 0.76+ projects that already have the minimum versions configured.
2
From your project’s Once implemented, these string values display to your end users as dismissable prompts explaining why the app requires certain permissions.
Info.plist
file (iOS: ios/YourApp/Info.plist
, macOS: macos/YourApp/Info.plist
), add the following key-value pairs:Tip: To view
Info.plist
as source code, right-click the file from the left sidebar in Xcode > click Open As > and then select Source Code from the menu.If desired, customize the default values for the permission prompts by replacing them with your preferred text.For example, if your end users prefer a language other than English, you can replace the default English strings with their language equivalents.
3
iOS only: Ensure your app continues to sync while it runs in the background by enabling Bluetooth LE background modes. Once enabled, your app continuously syncs in the background, even while the device is locked.
Note: Background modes are not available on macOS. This step only applies to iOS apps.
For official instructions, see Configuring background execution modes from Apple.
- From the left sidebar, click to select your project.
- Click Signing & Capabilities.
- Click + Capability, and then from the modal that appears, search and select Background Modes.
- From TARGETS, select your iOS app from the list.
- From Background Modes, toggle the following:
- Uses Bluetooth LE accessories
- Acts as a Bluetooth LE accessory

Android
From Android Studio, set up transport configurations for the Android target:1
Update Android’s minimum SDK version to
24
or higher:- Open the project-level
build.gradle
located in theandroid
root directory. - Set the
minSDKVersion
to24
.
2
Declaring Permissions in the Android ManifestAndroid requires certain permissions to be explicitly requested by the app to access features like Bluetooth Low Energy and Wi-Fi Aware. These permissions must be declared in the app’s manifest file and requested from the end user at runtime.The Ditto SDK’s Some of these permissions have an
AndroidManifest.xml
includes all of the necessary permissions for enabling its mesh network capabilities. These permissions will automatically be merged with your app’s permissions, so you should be aware of them.android:maxSdkVersion
attribute which means they are not used on devices running newer versions of Android. This is a best practice to respect users’ privacy when those permissions are not necessary.However, some apps may still need to use one or more of the above permissions across more versions of Android. This can be accomplished by overriding the permission configuration in your app’s AndroidManifest.xml
To override any of these permission limitations in your app, do the following:1
Open the
AndroidManifest.xml
located in the app/src/main
directory of your project.2
Within the same Note the additional
<manifest>
tag, just before the <application>
tag, add the relevant permissions you want to configure (location example):tools:remove
attribute. This tells the manifest merger to selectively remove the android:maxSdkVersion
behavior from the associated permissions, changing them to apply to all Android versions.For more information, see the official Permissions on Android and Merge manifest files documentation.
3
Add the following code snippet to the module-level
build.gradle
located in the android/app
directory:4
Start the app in Metro:
Handling Permissions
Within your default React component (App
), use this helper function to request permissions if developing for the Android target:
Setting Up Authentication
Create an identity object, define your authentication type, and then provide access credentials. Each instance of Ditto running in your app must prove its identity to other peers to sync. There are two types of identities you can use to authenticate:onlinePlayground
— Explore platform features and functionality without setting up your authentication mechanism.onlineWithAuthentication
— If developing a production-level app, integrate your own identity provider, such as Auth0, identify users, give users read or write control, and integrate with your existing authentication systems.
onlinePlayground
Use an online playground identity for development. You can find authentication details for your app on the Ditto Portal. Use these to set up your identity:JS
onlineWithAuthentication
Use theonlineWithAuthentication
identity when developing a production app for deployment.
Creating a New Instance of Ditto
Within atry/catch
statement, instantiate a new Ditto
object with the identity you’ve specified:
Setting Transport Configurations
UsingupdateTransportConfig
, do the following to set up transport configurations in your app:
1
Configure peer-to-peer transport settings so that all desired transport types available on the end-user device are available to Ditto.
2
Specify how you want Ditto to handle which transports to sync data across the mesh.
Constructing Sync Subscription Logic
Create the logic that performs sync and data operations in your app, including registering subscriptions, executing store operations, and observing changes in the given collection. For example, the following snippet defines a document object (document
), creates a subscription for the Cars
collection, executes database operations and logs the results, registers an observer for watching changes in the Cars
collection:
Starting the Sync Process
To start syncing with other peers in the mesh:Setting Up Presence
Monitor remote peers in the logs or using Ditto’s Presence Viewer app. For more information, see the blog post “An explanation of the Ditto Presence Viewer.” To set up presence observations:Setting Logs to Debug Level
Capture database debug logs by setting the Ditto log level to Debug mode. That way, any potential issues are tracked. To set the minimum log level toDebug
:
Declaring a Foreground Service (Android Only)
A foreground service allows your app to continue syncing data with Ditto while running in the background. A foreground service is not required to use Ditto, but without it your app will stop syncing whenever it is in the background. To declare the foreground service, add the following to yourAndroidManifest.xml
:
small_app_icon
drawable must be monochrome white.
The foreground service will be automatically started and stopped on startSync()
and stopSync()
, respectively.
Known issues
- React Native’s Fast Refresh will throw an error with the current Ditto architecture, insisting you provide a different persistence directory name. Currently, no workaround is available; however, developers can disable Fast Refresh to avoid this issue. Our team is actively working on a fix, and we appreciate your patience as we address this challenge.