Skip to content
Titanium SDK

Using modules

Written for Titanium SDK 13.4.0 and later

Two different things get added to a Titanium project and both are called dependencies.

A native module wraps platform code the core SDK does not expose: Bluetooth, maps, barcodes. It ships as a built binary per platform.

An npm package is JavaScript. If it runs without Node's built-ins and without a browser, it will probably run here.

Native modules

The modules directory lists what TiDev maintains. Installing one is three steps: unpack it, declare it, require it.

Note

There is no install command yet. ti module has one subcommand, list, so unpacking is done by hand. ti module install and ti module search are planned; until they ship, this is the path.

Download the release archive for the module and unzip it into a modules directory beside tiapp.xml. The archive already carries the right shape, so unzipping it in place gives you:

modules/
  android/ti.map/5.7.0/
  iphone/ti.map/7.3.1/

That is modules/<platform>/<id>/<version>/, and the platform directory is android, iphone or commonjs - iphone covers iPad and macOS too.

Check the CLI can see it:

ti module list

It reports three scopes - project, configured paths, and global - so the output also tells you which copy a build will pick up.

Then declare it in tiapp.xml, per platform:

<modules>
  <module platform="android">ti.map</module>
  <module platform="iphone">ti.map</module>
</modules>

Both steps are needed. A module on disk that tiapp.xml does not name is not built in, and the failure is a require that returns nothing rather than an error at build time.

Then require it by id:

const Map = require('ti.map');

Pin a version when more than one is unpacked and you care which one you get:

<module platform="android" version="5.7.0">ti.map</module>

Without a version the newest installed copy wins, which means a machine with two versions in modules/ and a colleague's machine with one can produce different builds from the same commit.

Important

A module is native code, so it is built for specific platforms and against a range of SDK versions. A module that has not been rebuilt for a newer Titanium SDK may fail at build time with a linker error rather than anything that names the module. Check the module's own page for the versions it supports.

Where modules live

modules/<platform>/<moduleid>/<version>/ in the project, which is committed like any other source. Some teams keep them out of version control and install in CI instead; either works, as long as the whole team does the same thing.

Unpacking into the global directory instead makes the module available to every project on that machine and to nobody else's, which makes a build depend on the machine it runs on. Prefer the project-local copy. On macOS the global one is ~/Library/Application Support/Titanium/modules, and ti module list prints the full path of everything it finds.

npm packages

package.json in the project root, and npm install as normal:

npm install lodash
const _ = require('lodash');

Titanium bundles what is in node_modules at build time. There is no resolution at runtime, so a package pulled in dynamically by name computed at runtime will not be there.

What will not work: anything that needs Node's built-ins (fs, net, child_process), anything that needs a DOM, and anything shipping native bindings. A package that only touches Ti.* and plain JavaScript is fine. Check before adopting a large dependency; the failure arrives at runtime as an undefined require.

Keep node_modules out of version control as you would anywhere else.

Which one do I need

If it talks to hardware, the operating system, or a platform SDK, it is a native module and somebody has to have written it. If it is an algorithm, a parser, or a client for an HTTP API, it is probably an npm package.

If neither exists, writing a native module is covered under Extending Titanium.

Next

Debugging and profiling covers finding out why the thing you just added is not working.

Edit this page on GitHubLast updated Nov 9, 2026