Building from source
The npm package ships prebuilt native libraries in packages/nativescript-masonkit/platforms/. You only need to rebuild them when you change Rust, Kotlin, Swift or C++ code. TypeScript changes only need the package rebuild at the end of this page.
Prerequisites
- Node 22 or later (CI uses 22).
- Rust via rustup. Keep it current with
rustup update. - cbindgen (
cargo install cbindgen). The iOS build regenerates the C headers with it on every build. - Android: the Android SDK with an NDK installed, and JDK 17.
- iOS: Xcode on macOS.
- Windows: see Windows.
Rust targets:
# Android
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
# iOS (device, Apple Silicon simulator, Intel simulator)
rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-iosvisionOS is a tier-3 Rust target with no prebuilt standard library. It builds with nightly and -Z build-std, so it also needs:
rustup toolchain install nightly
rustup component add rust-src --toolchain nightlyAndroid AAR
The Kotlin library builds the Rust crate itself through the rust-android-gradle plugin, so one Gradle command produces the whole AAR:
cd packages/nativescript-masonkit/src-native/mason-android
./gradlew :masonkit:assembleRelease -Prust.targets=all
cp masonkit/build/outputs/aar/masonkit-release.aar ../../platforms/android/Or run both steps with the package script:
cd packages/nativescript-masonkit
npm run build:android-Prust.targets picks the ABIs: all (arm, arm64, x86, x86_64), a comma-separated list such as arm64,x86_64, or leave it out to build only your host architecture, which is much faster while iterating.
Environment traps
Both of these fail with a one-line BUILD FAILED that says nothing about the cause.
rustcandcargomust be on the Gradle daemon'sPATH, not just your shell's. The failure readsA problem occurred starting process 'command 'rustc''. After changing your environment, run with--no-daemon(or./gradlew --stopfirst).A Rust build script runs
python, notpython3. On macOS/usr/bin/python3is an Xcode shim that fails when invoked aspython. Put a real shim ahead of it onPATH:sh#!/bin/sh exec /usr/bin/python3 "$@"
Check the AAR timestamp
A failed assembleRelease can leave the previous AAR in masonkit/build/outputs/aar. Check its modification time before copying it, or you will ship the old binary.
iOS xcframework
The Xcode project has a Build Mason Rust build phase (src-native/mason-ios/Mason/pre-build.sh) that regenerates the C headers with cbindgen and builds the mason-ios crate for each architecture Xcode is building. So the framework build is one script:
cd packages/nativescript-masonkit/src-native/mason-ios
./build.sh # iOS device + simulator
INCLUDE_VISIONOS=1 ./build.sh # plus visionOS device + simulator
rm -rf ../../platforms/ios/Mason.xcframework
cp -R dist/Mason.xcframework ../../platforms/ios/build.sh builds Release frameworks for each SDK and combines them into dist/Mason.xcframework.
The package script does the visionOS build and the copy in one step:
cd packages/nativescript-masonkit
npm run build:iosnpm run build:native runs build:android and then build:ios.
pre-build.sh reads your shell profile
The Xcode build phase runs source $HOME/.cargo/env and source $HOME/.profile under set -e. If either file is missing the phase fails, so make sure both exist and put cargo, rustc and cbindgen on PATH there.
Windows component
cd packages/nativescript-masonkit/src-native/windows
pwsh ./publish.ps1This builds the mason-windows crate and the C++/WinRT component for x64 and ARM64 and copies the binaries into platforms/windows/. Prerequisites and the native test harness are on the Windows page.
Manual Rust builds
You rarely need these, since Gradle and Xcode drive Cargo for you. To check that a crate compiles for a target:
cargo build --release -p mason-ios --target aarch64-apple-ios
cargo build -p mason-android --target aarch64-linux-androidBuilding mason-android by hand needs the NDK's clang as the linker. If you see error: linking with 'cc' failed, point Cargo at the NDK toolchain (adjust the NDK version and host to yours):
export ANDROID_NDK=$ANDROID_HOME/ndk/<version>
export PATH=$PATH:$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin
export CC_aarch64_linux_android=aarch64-linux-android21-clang
export AR_aarch64_linux_android=llvm-ar
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER=aarch64-linux-android21-clangThe same three variables exist for armv7_linux_androideabi (armv7a-linux-androideabi21-clang), i686_linux_android and x86_64_linux_android.
./tools/scripts/build-headers.sh regenerates every cbindgen header (iOS, Android and the C ABI) from the repo root.
Rebuilding the package
The demo apps (all except apps/demo) consume the built package from dist/. After TypeScript or native changes:
npx nx run nativescript-masonkit:build.allThis compiles the TypeScript and the Angular, Vue and Svelte entry points, and copies platforms/ into dist/packages/nativescript-masonkit. @nx/js:tsc infers ESM from the tsconfig and writes "type": "module" into the dist package.json, which would make Node load nativescript.webpack.js as ESM; tools/scripts/build-finish.ts restores the source package's type and module fields.
Running a demo
cd apps/demo-solid
ns run ios
ns run androidOr pick a demo from the npm start menu. Two things to know:
ANDROID_HOMEmust be exported in the shell that runsns run android.ns run iosneedsLANGandLC_ALLset (for exampleen_US.UTF-8), or the CocoaPods check fails.
Native library changes need ns run to be stopped and started again; livesync only reloads JavaScript.