npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nativescript-compass

v1.0.1

Published

A NativeScript plugin for compass functionality with native performance optimization

Readme

NativeScript Compass Plugin

npm npm

A NativeScript plugin that provides native compass functionality for both Android and iOS platforms. The plugin uses native sensor fusion algorithms and optimizes performance by minimizing JavaScript ↔ Native bridge calls.

Features

  • Native Performance: Sensor fusion and filtering implemented in native code
  • Cross-platform: Unified API for both Android and iOS
  • Sensor Fusion: Uses gyroscope + accelerometer/magnetometer on Android for improved accuracy
  • Configurable: Customizable update intervals, filtering, and platform-specific options
  • TypeScript: Full TypeScript definitions included
  • Optimized: Minimal JavaScript bridge calls for smooth performance

Installation

npm install nativescript-compass

Permissions

Android

The plugin automatically adds the required sensor features to your AndroidManifest.xml:

<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="false" />
<uses-feature android:name="android.hardware.sensor.compass" android:required="false" />
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="false" />

iOS

Add location permission to your Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app uses compass for navigation and orientation features.</string>

API Reference

Import

import { Compass } from 'nativescript-compass';

Methods

isAvailable(): boolean

Check if compass functionality is available on the device.

if (Compass.isAvailable()) {
    console.log('Compass is available');
}

startUpdating(options, onReading, onError?): Promise<boolean>

Start continuous compass updates.

const success = await Compass.startUpdating(
    options,           // CompassOptions
    onReading,         // (reading: CompassReading) => void
    onError            // (error: string) => void (optional)
);

stopUpdating(): boolean

Stop compass updates.

const stopped = Compass.stopUpdating();

getCurrentReading(options?): Promise<CompassReading>

Get a single compass reading.

const reading = await Compass.getCurrentReading();
console.log(`Heading: ${reading.heading}°`);

Interfaces

CompassOptions

interface CompassOptions {
    // Minimum change in degrees to trigger callback (after filtering)
    minChangeThreshold?: number;      // default: 3

    // Minimum interval between callbacks in milliseconds
    updateThrottle?: number;          // default: 200

    // Smoothing filter coefficient: 0.0 = no filter, 1.0 = maximum smoothing
    // Note: Only used on Android. iOS uses hardware-level filtering
    filter?: number;                  // default: 0.8

    android?: {
        useSensorFusion?: boolean;    // Use gyroscope + accelerometer/magnetometer (default: true)
        sensorDelay?: 'fastest' | 'game' | 'ui' | 'normal'; // Sensor polling rate (default: 'ui')
    };

    ios?: {
        usesTrueHeading?: boolean;    // Use true north instead of magnetic (default: false)
        headingFilter?: number;       // minimum degrees change for hardware update (default: minChangeThreshold)
    };
}

CompassReading

interface CompassReading {
    heading: number;                  // 0-360 degrees from north
    accuracy: number;                 // Accuracy in degrees (lower = better)
    timestamp: number;                // Reading timestamp

    // Optional fields (only if available)
    magneticHeading?: number;         // If different from heading
    trueHeading?: number;             // Only on iOS if usesTrueHeading=true
}

Usage Examples

Basic Usage

import { Compass } from 'nativescript-compass';

export class CompassPage {
    async onLoaded() {
        if (!Compass.isAvailable()) {
            alert('Compass not available on this device');
            return;
        }

        await this.startCompass();
    }

    private async startCompass() {
        try {
            await Compass.startUpdating(
                {}, // Use default options
                (reading) => {
                    console.log(`Heading: ${reading.heading}°`);
                    this.updateCompassDisplay(reading.heading);
                },
                (error) => {
                    console.error('Compass error:', error);
                }
            );
        } catch (error) {
            alert('Failed to start compass: ' + error);
        }
    }

    onUnloaded() {
        Compass.stopUpdating();
    }
}

Advanced Configuration

const options = {
    minChangeThreshold: 1,    // High sensitivity - trigger on 1° change
    updateThrottle: 100,      // Update max every 100ms
    filter: 0.9,              // Strong smoothing
    android: {
        useSensorFusion: true,   // Use gyroscope for better accuracy
        sensorDelay: 'game'      // Higher polling rate for responsive app
    },
    ios: {
        usesTrueHeading: true,   // Use geographic north
        headingFilter: 0.5       // Hardware updates every 0.5°
    }
};

await Compass.startUpdating(options, onReading, onError);

Single Reading

try {
    const reading = await Compass.getCurrentReading();
    console.log(`Current heading: ${reading.heading}°`);
    console.log(`Accuracy: ${reading.accuracy}°`);
} catch (error) {
    console.error('Failed to get compass reading:', error);
}

Performance Tuning

// High-performance real-time app (navigation, AR)
const highPerformanceOptions = {
    minChangeThreshold: 0.5,
    updateThrottle: 50,      // 20 updates per second
    filter: 0.95,            // Strong smoothing
    android: {
        useSensorFusion: true,
        sensorDelay: 'fastest' // ~200Hz polling
    },
    ios: {
        headingFilter: 0.1       // Very sensitive
    }
};

// Standard compass app
const standardOptions = {
    minChangeThreshold: 3,
    updateThrottle: 200,
    filter: 0.8,
    android: {
        sensorDelay: 'ui'        // Default: good balance
    }
};

// Battery-saving indicator
const lowPowerOptions = {
    minChangeThreshold: 5,
    updateThrottle: 500,
    filter: 0.5,
    android: {
        useSensorFusion: false,
        sensorDelay: 'normal'     // ~5Hz polling
    }
};

Platform Differences

Android

  • Uses SensorManager with accelerometer, magnetometer, and optionally gyroscope
  • Timer-based throttling: Uses Timer to check data at regular intervals, combines with threshold checking
  • Sensor fusion (useSensorFusion: true, default): Combines gyroscope + accelerometer/magnetometer for smoother, more accurate readings with less jitter
  • Simple mode (useSensorFusion: false): Uses only accelerometer + magnetometer, faster but may be less stable
  • Sensor polling rates (sensorDelay):
    • 'fastest' (~200Hz): SENSOR_DELAY_FASTEST - High-precision apps, AR, gaming
    • 'game' (~50Hz): SENSOR_DELAY_GAME - Interactive apps, responsive UI
    • 'ui' (~16Hz): SENSOR_DELAY_UI - Default - good balance for most apps
    • 'normal' (~5Hz): SENSOR_DELAY_NORMAL - Battery-conscious apps
  • Accuracy reporting: Real sensor accuracy (1°-15°) from hardware status

iOS

  • Uses CoreLocation framework with CLLocationManager
  • True heading available when usesTrueHeading: true
  • Heading filter (headingFilter): Hardware-level filtering, default equals minChangeThreshold
  • Accuracy reporting: Real accuracy from CoreLocation (varies by device and conditions)
  • Requires location permission for compass functionality

Performance Notes

  • All filtering and throttling is performed in native code
  • Minimal JavaScript bridge calls for optimal performance
  • Configurable update rates to balance accuracy vs. battery life

Troubleshooting

Common Issues

  1. "Compass not available": Device lacks required sensors
  2. "Location permission denied" (iOS): Add NSLocationWhenInUseUsageDescription to Info.plist
  3. Erratic readings: Try increasing filter value or minChangeThreshold
  4. Battery drain: Increase updateThrottle or disable useSensorFusion

Best Practices

  • Always check isAvailable() before starting compass
  • Stop compass updates when not needed (onUnloaded, onDestroy)
  • Use appropriate updateThrottle for your use case
  • Test on real devices (simulators may not have sensors)

Requirements

  • NativeScript 8.0+
  • iOS 11.0+
  • Android API 21+

License

Apache-2.0