- Building Realm JS
The following dependencies are required. All except Xcode can be installed by following the setup instructions for MacOS section.
- Xcode latest Xcode with command line tools installed
- The latest Xcode should work, which can be downloaded from Mac App Store. To install older Xcode versions, Xcodes.app is highly recommended
- Node.js version 16 or later
- CMake 3.21.4 or later
- ClangFormat Used by the binding generator to format C++ code. You can install it through Homebrew:
brew install clang-format
- OpenJDK 8
- Android SDK 23+
- Optionally, you can install Android Studio
- Android NDK 23
- Android CMake
- Docker is used for testing. You can install it as a desktop app or through Homebrew:
brew install --cask docker
.
Moreover, in order to avoid introducing false positives in our analytics dataset, it is highly recommended to disable analytics by adding the following to your shell configuration:
export REALM_DISABLE_ANALYTICS=1
# Install brew
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
# Install nvm and cmake
brew install nvm cmake
# Install the latest LTS version of Node.js and set it as the default
nvm install --lts
# Install cmake
brew install cmake
First, install OpenJDK:
brew install --cask temurin
# Check this returns: openjdk version "18.0.1" 2022-04-19
# If not, check if you have a JAVA_HOME environment variable set pointing elsewhere.
java -version
Next you need to define some environment variables. The best way to do this is in your shell’s configuration file, e.g. ~/.zshrc
, then open a new terminal window or run source ~/.zshrc
to reload the config. Add the following:
# Location of your Android SDK
export ANDROID_HOME=$HOME/Library/Android/sdk
# Add the Android SDK tools to your PATH
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools
Then you can install the SDK and NDK by running: (you can alternatively do this via Tools > SDK Manager in Android Studio)
sdkmanager --install "platforms;android-31"
sdkmanager --install "ndk;23.1.7779620"
sdkmanager --install "cmake;3.18.1"
To improve compilation speed. you can use ccache:
# Install ccache
brew install ccache
# check path of ccache
which ccache
# Export the ccache variants of compilation tools
export PATH=<ccache location>/libexec:$PATH
To clone the Realm JS repository and install git submodules, dependencies, and subpackage dependencies, run:
git clone https://github.com/realm/realm-js.git
cd realm-js
git submodule update --init --recursive
npm install
In order to improve the accuracy of git blame
locally by ignoring commits in which the code was reformatted by an automated tool, run the following from inside the repository:
git config blame.ignoreRevsFile .gitignore-revs
On Windows the Realm JS repo should be cloned with symlinks enabled:
# run in elevated command prompt
git clone -c core.symlinks=true https://github.com/realm/realm-js
or manually create the symlinks using directory junctions if you already have the repo cloned:
# run in elevated command prompt
cd realm-js\react-native\android\src\main\jni
# remove src and vendor files
del src
del vendor
mklink /j "src" "../../../../../src/"
mklink /j "vendor" "../../../../../vendor"
cd realm-js\tests\ReactTestApp\android\app\src\main
# remove assets file
del assets
mklink /j assets "../../../../../data"
Note
If you have cloned the repo previously make sure you remove your node_modules
directory, as well as any node_modules
directory of any sub-directory, since it may contain stale dependencies which may cause the build to fail.
Visual Studio Code is the recommended editor for the best experience working with the Realm JS codebase.
You should check that VS Code is using the workspace version of TypeScript rather than the VS Code version. This should be automatically configured but does not always seem to take effect. You can do this by:
- Open the
realm-js
root directory in VS Code and open any TypeScript file - Press Shift+Cmd+P to open the command palette
- Start typing
select typescript version
to select theTypeScript: Select TypeScript Version
command - Ensure
Use Workspace Version
is selected.
If you are using Visual Studio Code as your editor, you can get greatly improved C++ Intellisense by installing the clangd extension, which should be recommended by VS Code when you open the repository. This should prompt you to disable the built in C++ extensions Intellisense, but if not you should do this in Settings, searching for cpp intelli
.
This extension picks up the build/compile_commands.json
file generated by CMake (symlinked in the root directory), enabling full Intellisense.
Other editors should also be able to be configured to use the compile_commands.json
file.
In most cases, it's not required to build the SDK explicitly. You can either simply download the package from npm
or run one of the test scripts in either of the integration-tests/environments
(which will drive the dependent build-scripts automatically). If you want to invoke these scripts manually, see the individual sections below:
Most of Realm JS is platform independent code (commonly referred to as the SDK), which is built explicitly by running:
npm run build:ts --workspace realm
You can build and bundle for iOS by running the following command from the root directory:
# Pre-build Realm Core into an XCFramework
npm run prebuild-apple --workspace realm
# Generate the JSI binding code (to be compiled when building the consuming app)
npm run bindgen:jsi --workspace realm
The resulting prebuilt binary is stored in packages/realm/prebuilds/apple
.
You can build and bundle for Android by running the following command from the root directory:
# Pre-build Realm Core into a CPack install directory
npm run prebuild-android --workspace realm
# Generate the JSI binding code (to be compiled when building the consuming app)
npm run bindgen:jsi --workspace realm
The resulting prebuilt binary is stored in packages/realm/prebuilds/android
.
You can build the native prebuilt binary for Node.js by running the following command from the root directory:
npm run build:node --workspace realm
The resulting prebuilt binary is the packages/realm/prebuilds/node/realm.node
file.
If you want to produce a prebuild (a OS +arch specific archive meant for distribution alongside the NPM archive):
npm run prebuild-node --workspace realm
The resulting prebuilt binary is stored in a packages/realm/prebuilds/realm-*.tar.gz
file.
On Windows you will need to set up the environment for node-gyp:
-
Option 1: Install
windows-build-tools
Node.js package# run in elevated command prompt (as Administrator) npm install -g --production windows-build-tools
-
Option 2: Manually install and configure as described in the node-gyp manual.
Note you may need to configure the build tools path using npm
npm config set msbuild_path "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe"
You also need to install openssl libraries with vcpkg:
git clone https://github.com/Microsoft/vcpkg
cd vcpkg
bootstrap-vcpkg.bat
vcpkg install openssl:x64-windows-static
mkdir C:\src\vcpkg\installed\x64-windows-static\lib
copy .\packages\openssl-windows_x64-windows-static\lib\libeay32.lib C:\src\vcpkg\installed\x64-windows-static\lib\
copy .\packages\openssl-windows_x64-windows-static\lib\ssleay32.lib C:\src\vcpkg\installed\x64-windows-static\lib
You can build Realm JS for ARM/Linux from source and include it in your own project.
The following instructions assume you are using Debian GNU/Linux or a derived distribution.
First you need to have your build environment set up:
apt install build-essential cmake git libssl-dev curl
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
source $HOME/.bashrc
nvm install 16 # you can use any supported node version
You can now build and bundle Realm JS from source:
export REALM_USE_SYSTEM_OPENSSL=1
git clone https://github.com/realm/realm-js
cd realm-js
git submodule update —-init —-recursive
npm install --ignore-scripts
npm run build:node --workspace realm
npm run build:ts --workspace realm
Finally, you can use Realm JS in your example project MyProject
:
cd MyProject
npm init -y # skip this if you've already initialised your project
npm install path/to/realm-js/packages/realm
Tip
To run any of the "scripts"
commands from one of the package.json
files directly from the root, use the "name"
value from the target package.json
as such: npm run <command name> --workspace <package.json name>
.
If you need to clean up build files and other untracked files (except for node_modules
directories), run the following command from the root directory:
npm run clean
API documentation is written using TypeDoc. To generate the documentation, run the following command from the root directory:
npm run docs --workspace realm
The generated docs can be found in packages/realm/docs/index.html
.
See the instructions in the integration-tests
directory.
To lint JavaScript and TypeScript source code files using eslint
, run the following command from the root directory:
npm run lint
To lint C++ source code files using clang-format
, run the following command from the root directory:
npm run lint:cpp
We use a .clang-format
file based on the one from realm-core
, but feel free to modify if required.
On Windows some of these targets are available as npm commands.
npm run eslint
npm run node-tests
npm run test-runners
The tests will spawn a new shell when running, so you need to make sure that new shell instances use the correct version of npm
. If you have Homebrew correctly installed, this should work. If it is not working, you can add the following to your preferred shell configuration:
export NVM_DIR="$HOME/.nvm"
. "$(brew --prefix nvm)/nvm.sh"
There are a couple of suggested workflows for testing your changes to Realm JS against real apps:
- Guide: Setting up watchman to copy changes from this package to an app
- Guide: Testing your changes against sample apps using a script
See Debugging C++ and Debugging React Native.
To debug failing Github Actions CI tests, it can be helpful to ssh
into the runner and test out the CI commands manually. This Github Action can be used to add a step into the workflow which pauses it and outputs details to ssh
into it: https://github.com/marketplace/actions/debugging-with-tmate
The relevant snippet is:
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
timeout-minutes: 30
If you add a new JNI method to RealmReactModule.java
, you will need to regenerate the auto-generated header file.
-
First you need to find some classpaths required to generate the header. In a terminal,
cd ~/.gradle/caches
and then run:find "$(pwd -P)" -name "jetified-react-native-0.69.1-debug" -exec find {} -name "classes.jar" \;
find "$(pwd -P)" -name "jetified-soloader-0.10.3" -exec find {} -name "classes.jar" \;
find "$(pwd -P)" -name "nanohttpd-2.2.0.jar"
-
Build up a classpath string (e.g. in the terminal or in a text editor):
- Start with
~/Library/Android/sdk/platforms/android-31/android.jar
- Add the first result for each of the above find commands to this string, separated by a
:
.
You should end up with something like:
~/Library/Android/sdk/platforms/android-31/android.jar:~/.gradle/caches/transforms-3/7d342974325594036ab59618107595df/transformed/jetified-react-native-0.69.1-debug/jars/classes.jar:~/.gradle/caches/transforms-3/6c67d7687cdaa9b6d194c80ea9a580e2/transformed/jetified-soloader-0.10.3/jars/classes.jar:~/.gradle/caches/modules-2/files-2.1/org.nanohttpd/nanohttpd/2.2.0/73a02117620b6cc7683a1ed6ae24c2f36e2a715/nanohttpd-2.2.0.jar
- Start with
-
Change to the
react-native/android/src/main/java
directory in your Realm JS checkout -
Run
javac -h ../../../../../src/android/ -classpath <CLASSPATH_STRING> io/realm/react/RealmReactModule.java
, replacing<CLASSPATH_STRING>
with the string you built up in step 2 -
Delete the
.class
files that thejavac
command created