> ## Documentation Index
> Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Build from source

# Build from Source

Build the React Native SDK from the repository and link it into your app.
Use this when you need to:

* Consume an unreleased branch
* Target an ABI the prebuilt package doesn't ship (e.g. Android `x86`)
* Apply a local patch
* Audit the native code before shipping

If you just want to use a published release, see [Installation](/sdk/react-native/installation).

## Prerequisites

* Rust toolchain (`rustup`)
* Node.js 20+
* Xcode 15+ with command-line tools (for iOS)
* Android NDK 26+ with `ANDROID_NDK_HOME` set (for Android)
* `cargo-ndk` installed: `cargo install cargo-ndk`

Add the required Rust targets once:

```bash theme={null}
# iOS
rustup target add aarch64-apple-ios aarch64-apple-ios-sim

# Android
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
```

## Build

From the `sdk/` directory:

```bash theme={null}
# Full archive: iOS + Android native + JS bundle + tarball
make rn-archive
```

This produces `packages/privacy-boost-react-native/sunnyside-io-privacy-boost-react-native-<version>.tgz`.

### Granular targets

If you only need one platform or want to skip ahead:

| Target            | What it does                                                  |
| ----------------- | ------------------------------------------------------------- |
| `make rn-ios`     | Builds the iOS xcframework and regenerates TS bindings        |
| `make rn-android` | Builds Android `.a` per ABI and regenerates TS bindings       |
| `make rn-build`   | Typechecks, runs unit tests, and builds the JS bundle via bob |
| `make rn-mock`    | Regenerates only the Jest mock (if you're iterating on tests) |
| `make rn-archive` | All of the above, then `npm pack`                             |

## Install the tarball

In your RN app:

```bash theme={null}
npm install /path/to/sdk/packages/privacy-boost-react-native/sunnyside-io-privacy-boost-react-native-0.2.14.tgz
cd ios && pod install && cd ..
npx react-native run-ios   # or run-android
```

The tarball is a drop-in replacement for the published package — same entry
points, same types, same native modules.

## Developing against a local checkout

For tight iteration (edit Rust → rebuild → test in app), skip the tarball and
link the package directly. From your app:

```bash theme={null}
npm install /path/to/sdk/packages/privacy-boost-react-native
```

After editing Rust or the UDL, re-run the native build for the platform you're
testing:

```bash theme={null}
# In sdk/
make rn-ios          # or rn-android
```

Then restart Metro and reload your app. The native module gets picked up on
the next launch.

> **Gotcha:** JS changes in the SDK package need `make rn-build` or Metro
> won't see them. The `react-native` field in `package.json` points at `src/`,
> so Metro does resolve TS source directly — but `lib/` is what CJS/ESM
> consumers see.

## Common build errors

**`ANDROID_NDK_HOME not set`**
Install the NDK via Android Studio's SDK Manager, then:

```bash theme={null}
export ANDROID_NDK_HOME=$HOME/Library/Android/sdk/ndk/<version>
```

**`error: linker 'cc' not found` on Android build**
`cargo-ndk` isn't installed, or your toolchain is stale. Run
`cargo install cargo-ndk` and retry.

**`Found incorrect path in 'types' field` on `npm run build`**
You skipped the post-codegen patch step. The Makefile targets run it for you;
if you invoked `npm run ubrn:ios` directly, also run
`bash sdk/scripts/fix-ubrn-codegen.sh`.

**Tests fail with mock drift errors**
`make rn-mock` regenerates the Jest mock from the current bindings. Run it
after any UDL change.

## What gets built

```
packages/privacy-boost-react-native/
├── PrivacyBoostReactNativeFramework.xcframework/   # iOS binary
├── android/src/main/jniLibs/<abi>/                 # Android static libs
├── cpp/generated/                                   # JSI C++ bridge
├── src/generated/                                   # TS FFI bindings
└── lib/{commonjs,module,typescript}/                # Published JS/TS
```

Everything except `lib/` is gitignored — regeneration is expected on every
branch checkout that changes UDL or Rust source.
