React Native Installation and Setup
This guide covers setting up Jazz for React Native applications from scratch. If you're using Expo, please refer to the React Native - Expo guide instead. If you just want to get started quickly, you can use our React Native Chat Demo as a starting point.
Jazz supports the New Architecture for React Native.
Tested with:
"react-native": "0.78.22", "react": "18.3.1"
Installation
Create a new project
(Skip this step if you already have one)
npx @react-native-community/cli init myjazzapp cd myjazzapp
If you intend to build for iOS, you can accept the invitation to install CocoaPods. If you decline, or you get an error, you can install it with pod-install
.
Install dependencies
# React Native dependencies npm install @react-native-community/netinfo @bam.tech/react-native-image-resizer # React Native polyfills npm i -S @azure/core-asynciterator-polyfill react-native-url-polyfill readable-stream react-native-get-random-values @craftzdog/react-native-buffer @op-engineering/op-sqlite react-native-mmkv # Jazz dependencies npm i -S jazz-tools jazz-react-native jazz-react-native-media-images
Note: Hermes has added support for atob
and btoa
in React Native 0.74. If you are using earlier versions, you may also need to polyfill atob
and btoa
in your package.json
. Packages to try include text-encoding
and base-64
, and you can drop @bacons/text-decoder
.
Configure Metro
Regular repositories
If you are not working within a monorepo, create a new file metro.config.js
in the root of your project with the following content:
// metro.config.js const {
const getDefaultConfig: any
getDefaultConfig,const mergeConfig: any
mergeConfig } =require('@react-native/metro-config'); const
var require: NodeRequire (id: string) => any
config = {
const config: { resolver: { sourceExts: string[]; requireCycleIgnorePatterns: RegExp[]; }; }
resolver: {
resolver: { sourceExts: string[]; requireCycleIgnorePatterns: RegExp[]; }
sourceExts: string[]
sourceExts: ["mjs", "js", "json", "ts", "tsx"],requireCycleIgnorePatterns: RegExp[]
requireCycleIgnorePatterns: [/(^|\/|\\)node_modules($|\/|\\)/] } };var module: NodeModule
module.NodeJS.Module.exports: any
exports =const mergeConfig: any
mergeConfig(const getDefaultConfig: any
getDefaultConfig(var __dirname: string
__dirname),config);
const config: { resolver: { sourceExts: string[]; requireCycleIgnorePatterns: RegExp[]; }; }
Monorepos
For monorepos, use the following metro.config.js
:
// metro.config.js const
const path: any
path =require("path"); const {
var require: NodeRequire (id: string) => any
const makeMetroConfig: any
makeMetroConfig } =require("@rnx-kit/metro-config"); const
var require: NodeRequire (id: string) => any
const MetroSymlinksResolver: any
MetroSymlinksResolver =require("@rnx-kit/metro-resolver-symlinks"); // Define workspace root const
var require: NodeRequire (id: string) => any
const projectRoot: string
projectRoot =var __dirname: string
__dirname; constconst workspaceRoot: any
workspaceRoot =const path: any
path.resolve(const projectRoot: string
projectRoot, "../.."); // Add packages paths constextraNodeModules = {
const extraNodeModules: { modules: any; }
modules: any
modules:const path: any
path.resolve(const workspaceRoot: any
workspaceRoot, "node_modules"), }; constconst watchFolders: any[]
watchFolders = [const path: any
path.resolve(const workspaceRoot: any
workspaceRoot, "node_modules"),const path: any
path.resolve(const workspaceRoot: any
workspaceRoot, "packages"), ]; constconst nodeModulesPaths: any[]
nodeModulesPaths = [const path: any
path.resolve(const projectRoot: string
projectRoot, "node_modules"),const path: any
path.resolve(const workspaceRoot: any
workspaceRoot, "node_modules"), ];var module: NodeModule
module.NodeJS.Module.exports: any
exports =const makeMetroConfig: any
makeMetroConfig({resolver: {
resolver: { resolveRequest: any; extraNodeModules: { modules: any; }; nodeModulesPaths: any[]; }
resolveRequest: any
resolveRequest:const MetroSymlinksResolver: any
MetroSymlinksResolver(),extraNodeModules,
extraNodeModules: { modules: any; }
nodeModulesPaths: any[]
nodeModulesPaths, },sourceExts: string[]
sourceExts: ["mjs", "js", "json", "ts", "tsx"],watchFolders: any[]
watchFolders, });
Additional monorepo configuration (for pnpm)
- Add
node-linker=hoisted
to the root.npmrc
(create this file if it doesn't exist). - Add the following to the root
package.json
:
// package.json "pnpm": { "peerDependencyRules": { "ignoreMissing": [ "@babel/*", "typescript" ] } }
Add polyfills
Create a file polyfills.js
at the project root with the following content:
// polyfills.js import {
import polyfillGlobal
polyfillGlobal } from 'react-native/Libraries/Utilities/PolyfillFunctions'; import {class Buffer
Buffer } from "@craftzdog/react-native-buffer";import polyfillGlobal
polyfillGlobal("Buffer", () =>class Buffer
Buffer); // polyfill Buffer import {import ReadableStream
ReadableStream } from "readable-stream";import polyfillGlobal
polyfillGlobal("ReadableStream", () =>import ReadableStream
ReadableStream); // polyfill ReadableStream import "@azure/core-asynciterator-polyfill"; // polyfill Async Iterator import "@bacons/text-decoder/install"; // polyfill Text Decoder import 'react-native-get-random-values'; // polyfill getRandomValues
Update index.js
:
// index.js import { AppRegistry } from 'react-native'; import
import App
App from './App'; import { name asimport appName
appName } from './app.json'; import './src/polyfills'; AppRegistry.function AppRegistry.registerComponent(appKey: string, getComponentFunc: ComponentProvider, section?: boolean): string
registerComponent(import appName
appName, () =>import App
App);
Lastly, ensure that the "main"
field in your package.json
points to index.js
:
// package.json { "main": "index.js", ... }
Authentication
Jazz provides authentication to help users access their data across multiple devices. For details on implementing authentication, check our Authentication Overview guide and see the React Native Chat Demo for a complete example.
Next Steps
Now that you've set up your React Native project for Jazz, you'll need to:
- Set up the Jazz Provider - Configure how your app connects to Jazz
- Add authentication (optional) - Enable users to access data across devices
- Define your schema - See the schema docs for more information
- Run your app:
npx react-native run-ios npx react-native run-android
Verification
Ready to see if everything's working? Let's fire up your app:
npx react-native run-ios # or npx react-native run-android
If all goes well, your app should start up without any angry red error screens. Take a quick look at the Metro console too - no Jazz-related errors there means you're all set! If you see your app's UI come up smoothly, you've nailed the installation.
If you run into any issues that aren't covered in the Common Issues section, drop by our Discord for help.
Common Issues
- Metro bundler errors: If you see errors about missing polyfills, ensure all polyfills are properly imported in your
polyfills.js
file. - iOS build failures: Make sure you've run
pod install
after adding the dependencies. - Android build failures: Ensure your Android SDK and NDK versions are compatible with the native modules.
Install CocoaPods
If you're compiling for iOS, you'll need to install CocoaPods for your project. If you need to install it, we recommend using pod-install
:
npx pod-install