# How to Build JSAR for macOS or Android: A Complete Guide

> Build JSAR for macOS or Android with our complete guide. Follow simple steps using Node.js and Rust to create native libraries efficiently.

- Repository: [M Creative Lab/jsar-runtime](https://github.com/m-creativelab/jsar-runtime)
- Tags: how-to-guide
- Published: 2026-03-06

---

**To build JSAR for macOS or Android, install Node.js 18 and Rust nightly, add the target architectures (`aarch64-apple-darwin` and `x86_64-apple-darwin` for macOS, or `aarch64-linux-android` for Android), run `npm install && make jsbundle`, then execute `make darwin` or `make android` to produce the native libraries.**

JSAR is a cross-platform browser-engine library written in Rust that powers immersive web experiences. If you want to build JSAR for macOS or Android from the **m-creativelab/jsar-runtime** repository, you need to follow a specific toolchain setup involving Rust nightly, Node.js, and platform-specific compilation targets.

## Prerequisites for Building JSAR

Before compiling the native libraries, you must configure your development environment with the correct toolchain versions and Rust targets.

### Required Toolchain Versions

JSAR requires specific versions of Node.js and Rust to compile correctly:

- **Node.js 18.x** – Required for bundling the JavaScript shim and Web API implementations
- **Rust nightly toolchain** – The core runtime uses unstable Rust features

```bash

# Verify your versions

node -v               # Should show v18.x.x

rustc -V              # Should show 1.86.0-nightly or newer

rustup default nightly

```

### Platform-Specific Rust Targets

You must install the specific Rust targets for your intended platform. These targets enable cross-compilation to the correct architecture.

For **macOS** (universal binary support):

```bash
rustup target add aarch64-apple-darwin   # Apple Silicon (arm64)

rustup target add x86_64-apple-darwin    # Intel (x86_64)

```

For **Android**:

```bash
rustup target add aarch64-linux-android  # Android ARM64

```

## Building the JavaScript Bundle

JSAR embeds a JavaScript shim that implements Web APIs, HTML parsing, and DOM functionality. This code lives in the `lib/` directory and must be bundled before compiling the Rust code.

Run the following command from the repository root:

```bash
npm install && make jsbundle

```

This process:
1. Installs npm dependencies for the JavaScript shim
2. Bundles the TypeScript/JavaScript code into a static header file ([`libjsar_jsbundle.h`](https://github.com/m-creativelab/jsar-runtime/blob/main/libjsar_jsbundle.h))
3. Places the generated header in the build directory for CMake to embed into the final binary

## Compiling Native Libraries for macOS and Android

Once the JavaScript bundle is ready, you can compile the core Rust runtime. The build system uses a `makefile` front-end that orchestrates Cargo, CMake, and platform-specific toolchains.

### Build JSAR for macOS (Universal Binary)

To create a universal library that works on both Intel and Apple Silicon Macs:

```bash
make darwin

```

This command:
- Compiles the Rust core in `src/` to a static library
- Links against Skia for graphics rendering
- Produces `libjsar.dylib` as a universal binary containing both `x86_64` and `arm64` slices

The output appears in `build/darwin/release/` (or `debug/` if not using `RELEASE=yes`).

### Build JSAR for Android (ARM64)

To build for Android devices:

```bash
make android

```

This command:
- Uses the `aarch64-linux-android` target
- Links against the Android NDK toolchain
- Produces `libjsar.so` for ARM64 Android devices

The output appears in `build/android/release/`.

## Build Configuration Options

The `makefile` supports several flags to customize the build process:

| Flag | Effect | Example |
|------|--------|---------|
| `CLEAN=yes` | Removes the build directory before compiling | `make darwin CLEAN=yes` |
| `RELEASE=yes` | Compiles with `--release` profile for optimized binaries | `make darwin RELEASE=yes` |
| `INSPECTOR=yes` | Enables the built-in JavaScript debugger/inspector | `make android INSPECTOR=yes` |

## Key Source Files and Build System

Understanding the repository structure helps when troubleshooting build issues:

- **`makefile`** – The main entry point that defines `darwin` and `android` targets, orchestrating npm, Cargo, and CMake
- **[`Cargo.toml`](https://github.com/m-creativelab/jsar-runtime/blob/main/Cargo.toml)** – Rust package manifest listing dependencies including Skia and protobuf bindings
- **[`CMakeLists.txt`](https://github.com/m-creativelab/jsar-runtime/blob/main/CMakeLists.txt)** – Configures C++/Rust interop, builds Skia, and generates the embedded JS bundle header
- **`src/`** – Core Rust runtime implementation (DOM, WebGL, WebXR, etc.)
- **`lib/`** – JavaScript/TypeScript shim implementing Web APIs, bundled into the native library
- **`tools/`** – Helper scripts including [`setenv_android_toolchain.sh`](https://github.com/m-creativelab/jsar-runtime/blob/main/setenv_android_toolchain.sh) for Android NDK configuration
- **[`docs/development.md`](https://github.com/m-creativelab/jsar-runtime/blob/main/docs/development.md)** – Additional build notes and platform-specific troubleshooting

## Summary

- **JSAR** is a Rust-based browser engine that requires **Node.js 18** and the **Rust nightly toolchain** to build.
- You must install platform-specific targets: `aarch64-apple-darwin` and `x86_64-apple-darwin` for macOS, or `aarch64-linux-android` for Android.
- Run `npm install && make jsbundle` to generate the embedded JavaScript header before compiling native code.
- Use `make darwin` to produce a universal `libjsar.dylib` for macOS, or `make android` to produce `libjsar.so` for Android.
- Add `RELEASE=yes` for optimized builds, `CLEAN=yes` to wipe previous artifacts, or `INSPECTOR=yes` to enable debugging features.

## Frequently Asked Questions

### What version of Rust is required to build JSAR?

JSAR requires the **Rust nightly toolchain** (version 1.86.0-nightly or newer) because it uses unstable Rust features for its runtime implementation. You can set this as your default by running `rustup default nightly` before building.

### Can I build JSAR for iOS using the same process?

The current build system in the `makefile` specifically defines `darwin` and `android` targets. While the macOS target (`make darwin`) produces a universal binary for macOS architectures (x86_64 and arm64), building for iOS would require additional targets and toolchain configurations not currently documented in the standard build process.

### How do I enable the JavaScript inspector in my build?

To enable the built-in JavaScript debugger and inspector, append `INSPECTOR=yes` to your make command. For example: `make android INSPECTOR=yes` or `make darwin INSPECTOR=yes`. This flag compiles the runtime with debugging capabilities enabled, allowing you to inspect and debug the JavaScript execution within the JSAR environment.

### Where are the compiled library files located after building?

After running `make darwin`, the compiled `libjsar.dylib` appears in `build/darwin/release/` (or `build/darwin/debug/` if not using `RELEASE=yes`). For Android builds using `make android`, the `libjsar.so` file is located in `build/android/release/` (or the corresponding debug directory).