# macOS Setup

> Set up a Mac to build Titanium apps for iOS and Android.

- Source: https://titaniumsdk.com/docs/setup/macos
- Applies to: macOS, iOS, Android
- Written for Titanium SDK 13.4.0 and later.
- This corpus documents Titanium SDK 13.4.1. Anything here that does not name a version describes 13.4.1.
- Titanium is maintained by TiDev. The Appcelerator toolchain is retired: there is no `appc` CLI, no Appcelerator Studio and no hosted build service. The supported CLI is `titanium` on npm, invoked as `ti`.

---

## Install Node.js

Titanium requires **Node.js 22.19.0 or 24.x**.

> [!IMPORTANT]
> **Node 26 is only compatible with Titanium SDK 14 or newer.** Node 24
> works with every SDK.

**nvm**

```sh
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.41.0/install.sh | bash
```

Reopen your terminal, then:

```sh
nvm install 24
```

**Homebrew**

```sh
brew install node@24
```

Versioned formulas are keg-only. Add `$(brew --prefix node@24)/bin` to your
`PATH`.

**Installer**

Download the macOS `.pkg` from
[nodejs.org](https://nodejs.org/dist/latest-v24.x/).

```sh
node -v
```

## Install a JDK

Titanium requires **JDK 17, 21, or 25**. JDK 26 is only compatible with
Titanium SDK 14 or newer.
Any distribution works. The commands below install
[Temurin](https://adoptium.net/) or your distribution's OpenJDK.

**Homebrew**

```sh
brew install --cask temurin@21
```

**Installer**

Download the macOS `.pkg` from
[Adoptium](https://adoptium.net/temurin/releases/?version=21).

```sh
javac -version
```

## Set `JAVA_HOME`

Gradle and the Titanium SDK locate the JDK through `JAVA_HOME`. Most installers
leave it unset.

**zsh**

```sh
echo 'export JAVA_HOME=$(/usr/libexec/java_home -v 21)' >> ~/.zshrc
source ~/.zshrc
$JAVA_HOME/bin/javac -version
```

**bash**

```sh
echo 'export JAVA_HOME=$(/usr/libexec/java_home -v 21)' >> ~/.bash_profile
source ~/.bash_profile
$JAVA_HOME/bin/javac -version
```

**fish**

```fish
echo 'set -gx JAVA_HOME (/usr/libexec/java_home -v 21)' >> ~/.config/fish/config.fish
source ~/.config/fish/config.fish
$JAVA_HOME/bin/javac -version
```

The value stays unresolved on purpose: `/usr/libexec/java_home` reports where
the JDK is now, so an update cannot strand the path. Change `-v 21` if you
installed 17 or 25.

## Install the Titanium CLI

**npm**

```sh
npm install -g titanium
```

**pnpm**

```sh
pnpm add -g titanium
```

Prefix that with `sudo` if you installed Node with apt or the installer: their
global directory is owned by root.

```sh
ti -v
```

The command is also available as `titanium`:

```sh
titanium -v
```

## Install the Titanium SDK

The CLI is the tool you run; the SDK is what builds your app. You can have
several SDKs installed at once.

```sh
ti sdk install
```

With no version, that installs the latest stable release and makes it the
default. It is a few hundred megabytes.

```sh
ti sdk list
ti sdk list --releases
```

## Install Xcode

Xcode compiles, signs and installs iOS apps. Titanium drives it rather than
replacing it.

Install it from the Mac App Store, or from
[Apple's developer downloads](https://developer.apple.com/download/all/) for a
specific version. It is around 10 GB.

Open it once after installing: it finishes setting itself up on first launch,
and Titanium cannot use it before that. Then install the command line tools:

```sh
xcode-select --install
```

With more than one Xcode installed, point the toolchain at the one you mean:

```sh
sudo xcode-select -s /Applications/Xcode.app
```

### Which version

Titanium SDK 13.4 supports **Xcode 15.0 through 26.x**. A newer one is not
blocked: Titanium reports it as too new and builds anyway. If a build breaks
in a way that makes no sense, rule that out early.

### Simulators

Xcode installs one iOS runtime with itself. For others, open **Xcode → Settings
→ Components**.

SDK 13.4 builds with a minimum deployment target of **iOS 15.0**, so a simulator
older than that cannot run what you build.

## Set up signing for a device

A simulator build needs nothing. A real iPhone needs a development certificate
and a provisioning profile naming the device. Let Xcode create them:

1. **Xcode → Settings → Accounts**, add your Apple ID.
2. Select the team, choose **Manage Certificates**, add an **Apple Development**
   certificate.
3. Connect the device and let Xcode register it.

Titanium reads certificates from your keychain and profiles from
`~/Library/MobileDevice/Provisioning Profiles`, so `ti build -p ios -T device`
picks them up.

A free Apple ID covers your own device. Distributing to anyone else needs a paid
Apple Developer account. See [Distributing Apps](https://titaniumsdk.com/docs/distribute/signing.md).

## Install the Android SDK

Titanium needs four pieces of it:

| Component      | Why                   | Supported by SDK 13.4 |
| -------------- | --------------------- | --------------------- |
| SDK Platform   | Compiles against it   | API 23 to 36          |
| Build Tools    | Packages the APK      | 30.0.2 to 35.x        |
| Platform Tools | Provides `adb`        | 33.x                  |
| Emulator       | Runs a virtual device | Any current version   |

Android Studio is the straightforward way to get them. The command-line tools
are smaller and are what you want on a build server.

**Android Studio**

Install [Android Studio](https://developer.android.com/studio) and let the setup
wizard run. It installs a platform, build tools and platform tools.

Then open **Settings → Languages & Frameworks → Android SDK** and check that
**SDK Tools** lists **Android SDK Build-Tools**, **Android SDK Platform-Tools**
and **Android Emulator**.

**Command line**

Download the **command-line tools** from the
[Android Studio downloads page](https://developer.android.com/studio#command-line-tools-only)
and unzip them to `<sdk>/cmdline-tools/latest`. The tools expect that exact
layout and fail confusingly without it.

```sh
sdkmanager "platforms;android-36" "build-tools;35.0.0" "platform-tools" "emulator"
```

> [!NOTE]
> Google has deprecated `sdkmanager` in favour of `android sdk install
platforms/android-36 build-tools/35.0.0`. Both work. `sdkmanager` still ships
> in the command-line tools and is what most CI scripts call.

## Set the Android SDK path

```sh
ti setup android
```

`ti setup android` finds the SDK and writes the path to the CLI's config, so no
environment variable has to be right.

If you would rather set one, Titanium checks `ANDROID_SDK_ROOT` and
`ANDROID_SDK`, then looks for `adb` on your `PATH`, then scans the usual install
directories.

> [!IMPORTANT]
> `ANDROID_HOME` is not one of them. Most Android documentation tells you to set
> it; Titanium's app build does not read it.

## Versions newer than Titanium supports

Google ships API levels and build tools faster than the SDK adds support, so a
current Android Studio usually produces warnings:

```
!  Android API Android 17 (android-37) is too new and may or may not work with
   Titanium SDK 13.4.0.
   The maximum supported Android API level by Titanium SDK 13.4.0 is API level 36.
```

Titanium builds anyway. Leave them until a build fails, then pin a version it
knows:

```sh
ti config android.buildTools.selectedVersion 35.0.0
```

Android Studio installs the SDK to `~/Library/Android/sdk`, which the CLI already
checks.

## Set up an Android emulator

Create a virtual device with Android Studio's Device Manager. On Apple silicon,
choose an `arm64-v8a` system image: an x86 image runs under emulation and is
unusably slow.

A physical device over USB needs no driver on macOS. Turn on USB debugging in
Developer options and accept the prompt on the device.

## Verify Titanium is Ready

```sh
ti info
```

![A macOS terminal running ti info. It opens with the Titanium CLI and SDK versions, then lists what it detected under headings: Operating System, with the name, version, architecture, CPU count and memory; Node.js, with the Node.js and npm versions; Titanium CLI, with the CLI version; and the start of the installed Titanium SDKs.](https://titaniumsdk.com/docs/guides/ti-info-macos.png)

`ti info` lists everything it detected and any issues it found. A working setup
reports none.

Warnings are common and usually harmless: a component newer than the SDK
supports produces one, and so does a missing NDK. When something is wrong,
`ti info` names it and says what to do.

## Troubleshooting

### Every command exits with "Rebuild failed"

You are on Node 26 with SDK 13.4 or earlier. Switch to Node 24, or to SDK 14 -
[detail here](#install-node-js).

### `ti info` reports no iOS certificates

Open **Xcode → Settings → Accounts → Manage Certificates** and check an **Apple
Development** certificate is listed. Adding it there puts it in the login
keychain, which is where Titanium looks.

### Build Tools or API level "too new"

Warnings, not errors. Ignore them until a build fails, then pin a supported
version with the command in the message.

### `xcode-select` points at the wrong Xcode

```sh
xcode-select -p
```

If that names a beta or a version you removed, set it with
`sudo xcode-select -s`.

## Next

[Your first app](https://titaniumsdk.com/docs/build/first-app.md) creates a project and builds it.
