Library / SDK
petermetz/cordova-plugin-ibeacon avatar
petermetz/cordova-plugin-ibeacon

cordova-plugin-ibeacon: beacon ranging inside a Cordova app

An iBeacon plugin for Phonegap / Cordova 3.x and upwards. Supports both iOS and Android (contributions are welcome)

727 stars363 forksJavaScriptApache-2.0

At a glance

What is it?
cordova-plugin-ibeacon exposes iBeacon ranging, monitoring and region geofencing to JavaScript in Cordova and Phonegap apps on iOS and Android. It earns its place for cross-platform teams, with region monitoring and beacon advertising staying iOS-only.
Who is it for?
Adopt cordova-plugin-ibeacon if you already ship a Cordova or Phonegap app, need beacon features on both iOS and Android from one JavaScript codebase, and can accept a plugin installed straight from the git repository rather than a pinned tag.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A Cordova plugin that puts proximity beacons inside JavaScript

cordova-plugin-ibeacon is a Cordova and Phonegap plugin for proximity beacon monitoring and transmission, supporting iBeacons. The npm package carries the name com.unarin.cordova.beacon, and its package.json declares the Cordova plugin id com.unarin.cordova.beacon with the platform list ios and android. The version field reads 3.8.1 and the primary language is JavaScript.

The repository layout follows the standard Cordova plugin anatomy. A www directory holds the JavaScript layer that the app calls, plugin.xml describes the plugin to the Cordova toolchain, and src carries the native code for each platform, which is where the real beacon work happens on iOS and Android. A test directory, a tools directory and an eslint configuration sit alongside them.

The intended reader is a team that already has a Cordova application and wants beacons without building a separate native app or maintaining two codebases. The repository description states support for Phonegap and Cordova 3.x and upwards, and notes that contributions are welcome, which in practice points at Android parity rather than iOS features. This is a bridge, not a beacon stack: it does not scan for beacons itself, it wraps what the two operating systems already expose.

The CLLocationManager shape survives, the callbacks do not

The API deliberately mimics the one exposed through Apple's CLLocationManager as introduced in iOS 7, so a developer who knows that class can find most calls here. What changed across versions is the plumbing around it, and those changes are the real migration cost.

Since version 2 the main facade in the DOM is called LocationManager rather than IBeacon, and its API is built on promises instead of callbacks. The same version stopped polluting the global namespace, so every model class and utility now sits behind the cordova.plugins.locationManager reference chain. Since version 3.2 the Klass dependency was removed, and that removal changed how you create the delegate.

The practical consequence is that version 1 code does not run here. An application written against the old global IBeacon facade with per-event callbacks has to be rewritten around promises and the namespaced reference. The repository ships a CHANGELOG.md and a FAQ.md for that kind of question, but the README does not lay out a step-by-step migration table, so expect to read the source in www/LocationManager.js when upgrading an older app.

Region monitoring and beacon advertising stop at the iOS line

The feature matrix is where this plugin stops being symmetric. Ranging and monitoring work on both Android and iOS. Region monitoring, described in the README as geo fencing, is exclusive to iOS, and the documentation stresses that it works in all app states. Advertising the device itself as an iBeacon is also iOS-only.

Android has two features of its own. The first is an ARMA filter for distance calculations, which changes how proximity readings are interpreted on that platform. The second is the ability to disable the request for bluetooth permissions, useful when the host application already holds that permission or obtains it another way.

For a cross-platform product this is a hard boundary, not a preference. If a retailer wants shoppers to be geofenced into a store, that behaviour exists on iOS and has no Android counterpart in this plugin, so the app needs a separate path. The same applies to a phone acting as a beacon transmitter. The plugin does not document a fallback for those cases, and it does not describe how the platform differences are surfaced at runtime, so platform checks in your own code are on you.

Installing the plugin and describing a beacon region

Installation is a single Cordova command pointed at the git repository, which installs from the default v3.x branch rather than from a tagged release. Add it to a project like this:

code
cordova plugin add https://github.com/petermetz/cordova-plugin-ibeacon.git

After the install, the plugin is reached through the cordova.plugins.locationManager reference chain. A region is described by a BeaconRegion object, and the constructor takes the identifier first, then the UUID, then major and minor. The UUID and identifier are mandatory, while major and minor fall back to wildcard values when left empty. The constructor throws an error if the parameters are not valid, so an invalid region fails loudly at creation rather than silently failing to match anything.

This is how the README builds one:

code
    var uuid = '00000000-0000-0000-0000-000000000000'; // mandatory
    var identifier = 'beaconAtTheMacBooks'; // mandatory
    var minor = 1000; // optional, defaults to wildcard if left empty
    var major = 5; // optional, defaults to wildcard if left empty

The identifier is the application-side label you use to tell regions apart, and the UUID is the namespace shared with the beacon hardware. Keep them consistent with what the deployed beacons broadcast, otherwise monitoring starts without errors and simply never matches.

iOS 8 turned location permission into a runtime step

On iOS 8 you have to request permissions from the user of your app explicitly, and the plugin exposes that through its own API rather than leaving it to configuration. The LocationManager class offers requestWhenInUseAuthorization and requestAlwaysAuthorization for that purpose. A first run that calls startMonitoringForRegion before any authorization request will not work as expected.

A second iOS-specific requirement is the background mode. In order to use advertising, for example startAdvertising, the iOS capability Location updates is required, and the README gives the exact path in Xcode: your target, then Capabilities, then Background Modes, then Location updates. The same setting is what makes region monitoring work in all app states, since a geo fence that only fires while the app is foregrounded is not a geo fence in any useful sense.

These are build-time and runtime obligations that the Android side does not mirror in the same shape. The Android-specific ability to disable the request for bluetooth permissions tells you the plugin does touch permission handling on that platform, but the README does not describe an equivalent Android authorization call, so iOS remains the platform where the permission choreography is fully spelled out.

Monitoring and ranging answer different questions

The delegate object is where the answers arrive. The README example assigns three handlers: didDetermineStateForRegion, which reports whether the device is inside or outside the tracked region, didStartMonitoringForRegion, which confirms that monitoring actually started, and didRangeBeaconsInRegion, which delivers the ranging results with proximity information.

Ranging and monitoring are different jobs. Ranging is the active question, essentially how close is this beacon right now, and it answers only while the app is running. Monitoring is the passive question, did we enter or leave this region, and it keeps working in the background on iOS when the region monitoring feature and its background mode are configured.

Calls return promises, so failures are handled explicitly rather than through an error callback:

code
cordova.plugins.locationManager.setDelegate(delegate);
code
cordova.plugins.locationManager.startMonitoringForRegion(beaconRegion)
	.fail(function(e) { console.error(e); })
	.done();

The failure handler is worth keeping. Region identifiers must match what the hardware broadcasts, and a region built with the wrong UUID or an out-of-range major fails at runtime rather than at compile time. The plugin also offers appendToDeviceLog for writing a compact trace to the device log, which the README example uses alongside a DOM logger.

When a native Swift app is the better route

The realistic alternative is to drop the plugin and write the iOS half natively. The difference in approach is directness. Calling CLLocationManager yourself gives you the platform object with no bridge, no promise wrapper, no delegate shim and no plugin lifecycle, and every new Apple API is available the day it ships rather than when the plugin exposes it.

What the plugin buys in exchange is that the same JavaScript code path keeps working on Android. That is the whole argument for it, and it is a strong one for a team with one product across two operating systems. It is weak for an iOS-only product, where the plugin adds a layer you would otherwise write once and own yourself.

There is a middle option to consider first: keep Cordova for the application shell but confirm in plugin.xml which native modules are actually included for each platform before committing. The plugin exposes more on iOS than on Android, so a mixed codebase can end up with an iOS path that uses region monitoring and an Android path that quietly cannot, which is a bug your testers will find only if they run the flow on both platforms.

Version drift between the v3.x branch and the newest tag

The release history and the branch tell different stories, and that is worth understanding before you pin anything. The most recent GitHub releases are v3.7.0 dated 2018-07-25, v3.6.0 dated 2017-12-27 and 3.4.0 dated 2016-03-27. The default branch is v3.x, the last push was on 2026-10-18, and package.json already declares version 3.8.1. No release has been published for that version, so the branch has moved well past the newest tag.

For an installer this matters in a concrete way. The documented install command pulls from the git repository and therefore gets branch code, which is newer than anything you can install by tag. There is no released artifact to compare against, and no tag to point a build at for reproducibility.

The tooling shows the branch is still maintained as a working project rather than an abandoned one. The dev dependencies include eslint 9.36.0, husky 9.1.7 and the commitlint packages at 19.8.1, the scripts section defines a lint command running eslint on the project and a postinstall hook for husky, and the repository carries an eslint.config.js plus a .github directory. Licence is Apache 2.0 with the Apache LICENSE file at the repository root, which is a permissive grant that keeps commercial use straightforward.

Editorial conclusion

Adopt cordova-plugin-ibeacon if you already ship a Cordova or Phonegap app, need beacon features on both iOS and Android from one JavaScript codebase, and can accept a plugin installed straight from the git repository rather than a pinned tag. Do not adopt it if your product requires iOS-only capabilities such as region monitoring or acting as an iBeacon transmitter on Android, if you are a native Swift shop that can call CLLocationManager directly, or if you need an audited release tag, since the newest tag is v3.7.0 from 2018-07-25 while the default v3.x branch has moved on and package.json already declares 3.8.1. Verify three things first: install from git and check plugin.xml for the platform support you actually need, exercise requestWhenInUseAuthorization and requestAlwaysAuthorization on a real device running iOS 8 or later, and read the delegate creation change introduced in 3.2 before porting older callback-based code.

Frequently asked questions

How do I install cordova-plugin-ibeacon in a Cordova project?

The README gives a single command, cordova plugin add https://github.com/petermetz/cordova-plugin-ibeacon.git, which installs from the git repository and the default v3.x branch rather than from a tagged release. After installation the plugin is reached through the cordova.plugins.locationManager reference chain.

Does cordova-plugin-ibeacon work the same way on iOS and Android?

Ranging and monitoring are available on both platforms, but region monitoring, described as geo fencing, and advertising the device as an iBeacon are exclusive to iOS. Android adds an ARMA filter for distance calculations and the option to disable the request for bluetooth permissions.

How do I request location permission on iOS 8 or later with cordova-plugin-ibeacon?

The plugin exposes requestWhenInUseAuthorization and requestAlwaysAuthorization through its API, and the README states that on iOS 8 permissions must be requested explicitly from the user. Using advertising also requires the Location updates background mode, set in Xcode under your target, Capabilities, Background Modes.

Why did my delegate stop firing after upgrading cordova-plugin-ibeacon?

Two documented changes explain most breakages. Since version 2 the facade is LocationManager rather than IBeacon, the API is promise-based instead of callback-based, and everything sits under cordova.plugins.locationManager instead of the global namespace. Since version 3.2 the Klass dependency was removed, which changed how the delegate is created.

Which version of cordova-plugin-ibeacon should I depend on?

The newest GitHub release is v3.7.0 from 2018-07-25, while the default v3.x branch has moved beyond it, package.json declares 3.8.1, and the last push was on 2026-10-18. Installing from git therefore gives you branch code that is newer than any tagged release.

What licence does cordova-plugin-ibeacon use?

The repository is licensed under Apache 2.0, with the Apache LICENSE file at the root of the repository and the same licence recorded in package.json.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. petermetz/cordova-plugin-ibeacon on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/petermetz-cordova-plugin-ibeacon.svg)](https://hysenlabs.com/projects/petermetz-cordova-plugin-ibeacon)

Was this useful?