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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@ribcage/expo-performance

v1.0.4

Published

A performant module for tracking FPS and RAM usage in React Native applications

Readme

expo-performance

A performant Expo module for tracking FPS, RAM, and CPU usage in React Native applications.

Features

  • FPS Tracking: Real-time frame rate monitoring using native APIs
    • iOS: Uses CADisplayLink (same approach as React Native's performance monitor)
    • Android: Uses Choreographer.FrameCallback
  • RAM Usage Monitoring: Memory consumption tracking
    • iOS: Uses task_info with MACH_TASK_BASIC_INFO
    • Android: Uses ActivityManager and Debug.MemoryInfo
  • CPU Usage Monitoring: Basic CPU usage tracking
  • Cross-platform: Works on both iOS and Android
  • TypeScript: Full TypeScript support with type definitions
  • Performance Optimized: Minimal overhead, native implementations
  • Simple Class-based API: Single class with intuitive methods

Installation

npm install @ribcage/expo-performance

Usage

Basic Usage

import PerformanceMonitor from '@ribcage/expo-performance';

// Start monitoring with updates every second
const success = await PerformanceMonitor.startMonitoring((metrics) => {
  console.log(`FPS: ${metrics.fps.toFixed(1)}`);
  console.log(`RAM: ${metrics.ramUsageInMB.toFixed(2)} MB`);
  console.log(`CPU: ${metrics.cpuUsage.toFixed(1)}%`);
}, 1000);

// Get current metrics synchronously
const currentMetrics = PerformanceMonitor.getCurrentMetrics();
console.log(currentMetrics);

// Check if monitoring is active
console.log('Monitoring:', PerformanceMonitor.isMonitoring());

// Stop monitoring
PerformanceMonitor.stopMonitoring();

React Component Example

import React, { useEffect, useState } from 'react';
import { Text } from 'react-native';
import PerformanceMonitor, { PerformanceMetrics } from 'expo-performance';

function PerformanceDisplay() {
  const [metrics, setMetrics] = useState<PerformanceMetrics | null>(null);

  useEffect(() => {
    const startMonitoring = async () => {
      await PerformanceMonitor.startMonitoring(setMetrics, 1000);
    };
    
    startMonitoring();
    
    return () => {
      PerformanceMonitor.stopMonitoring();
    };
  }, []);

  return (
    <Text>
      {metrics ? 
        `FPS: ${metrics.fps.toFixed(1)} | RAM: ${metrics.ramUsageInMB.toFixed(1)}MB | CPU: ${metrics.cpuUsage.toFixed(1)}%` : 
        'Loading...'
      }
    </Text>
  );
}

API Reference

Types

interface PerformanceMetrics {
  fps: number;           // Current frames per second
  ramUsageInMB: number;  // Memory usage in megabytes
  cpuUsage: number;      // CPU usage percentage
  timestamp: number;     // Timestamp when metrics were captured
}

type PerformanceCallback = (metrics: PerformanceMetrics) => void;

PerformanceMonitor Class Methods

startMonitoring(callback, intervalMs?): Promise<boolean>

Starts monitoring performance metrics.

  • callback: Function to receive performance updates
  • intervalMs: Update interval in milliseconds (default: 1000)
  • Returns: Promise that resolves to success status

stopMonitoring(): void

Stops performance monitoring.

getCurrentMetrics(): PerformanceMetrics

Gets current performance metrics synchronously.

isMonitoring(): boolean

Check if monitoring is currently active.

getDetailedMemoryInfo(): DetailedMemoryInfo | null

Get detailed memory information (platform-dependent).

getSystemInfo(): SystemInfo | null

Get system information (platform-dependent).

addListener(callback): Subscription

Add additional listener for performance updates.

forceGarbageCollection(): void

Force garbage collection (if supported by platform).

Implementation Details

FPS Tracking

iOS Implementation:

  • Uses CADisplayLink attached to the main run loop
  • Counts frames over 1-second intervals
  • Calculates FPS as frameCount / elapsed_time
  • Similar approach to React Native's RCTFPSGraph

Android Implementation:

  • Uses Choreographer.FrameCallback for frame callbacks
  • Tracks frame timestamps and calculates FPS
  • Runs on the main thread for accurate UI frame tracking

RAM Usage Tracking

iOS Implementation:

  • Uses task_info() with MACH_TASK_BASIC_INFO
  • Reports resident_size (physical memory footprint)
  • Same approach as React Native's RCTGetResidentMemorySize

Android Implementation:

  • Uses Debug.MemoryInfo() for memory statistics
  • Reports totalPrivateDirty (private dirty memory)
  • More accurate than ActivityManager.getMemoryInfo()

Performance Considerations

  • Minimal Overhead: Native implementations with efficient monitoring
  • Automatic Cleanup: Subscriptions automatically clean up resources
  • Thread Safe: All operations are thread-safe
  • Memory Efficient: No memory leaks, proper resource management

Example App

See the example/App.tsx file for a complete example showing:

  • Real-time performance monitoring
  • Performance history tracking
  • UI controls for starting/stopping monitoring
  • Performance test components

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.