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

react-native-memory-footprint

v0.3.0

Published

Get memory footprint of your app

Readme

react-native-memory-footprint

A tiny React Native library for reading how much memory your app is really using, on iOS and Android.

This library reports each platform's own definition of "real" usage:

  • iOS: phys_footprint, the same number shown in Xcode's memory gauge, and what Jetsam uses to decide whether to kill your app
  • Android: anonymous RSS + swap, the same metric Google's own Play Vitals uses to flag apps for excessive memory usage

Installation

npm install react-native-memory-footprint

Usage

import { getMemoryFootprint } from 'react-native-memory-footprint';

const bytes = getMemoryFootprint();
console.log(`${(bytes / 1024 / 1024).toFixed(2)} MB`);
import { sampleMemoryFootprint } from 'react-native-memory-footprint';

// Read the footprint every 500ms for 5s (both configurable).
const { samples } = await sampleMemoryFootprint();
const valid = samples.filter((bytes) => bytes >= 0);
const toMB = (bytes) => (bytes / 1024 / 1024).toFixed(2);
if (valid.length === 0) {
  console.log('no readings succeeded');
} else {
  console.log(`first: ${toMB(valid[0])} MB`);
  console.log(`last: ${toMB(valid[valid.length - 1])} MB`);
  console.log(`peak: ${toMB(Math.max(...valid))} MB`);
}

API

getMemoryFootprint(): number

Returns the current memory footprint of the app process, in bytes.

| Platform | Underlying metric | | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | iOS | phys_footprint from task_info(TASK_VM_INFO), the same value shown in Xcode's memory gauge and used by Jetsam | | Android | Anonymous RSS + swap (RssAnon + VmSwap from /proc/self/status), the same metric behind Play Console's "excessive memory usage" vitals |

sampleMemoryFootprint(options?): Promise<SampleMemoryFootprintResult>

Reads the memory footprint every interval ms for duration ms (natively, so timing isn't affected by JS-thread load) and resolves with the collected readings.

| Option | Default | Description | | ---------- | ----------- | -------------------------------- | | interval | 500 (ms) | How often to read the footprint. | | duration | 5000 (ms) | Total time to keep sampling. |

Both must be numbers >= 1; fractional values are rounded to whole ms. A < 1 or non-finite value rejects the promise with a RangeError.

Result:

| Field | Type | Description | | --------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | samples | number[] | Footprint readings in bytes, oldest first. samples[0] is read immediately when sampling starts; the rest follow one per interval. A reading that failed is -1 (same sentinel as getMemoryFootprint()). |

To cancel early — e.g. on component unmount — pass an AbortSignal as { signal } in the second argument. The promise then rejects with an AbortError (handle it with .catch), and aborting one call never affects other concurrent calls.

const { samples } = await sampleMemoryFootprint(
  { interval: 250, duration: 10000 },
  { signal }
);

How iOS memory footprint is calculated

Per WWDC 2018 Session 416, "iOS Memory Deep Dive", Apple's own mental model for phys_footprint is:

App memory = Dirty + Compressed. Clean memory is not considered being used.

Only memory your app has actually written to (dirty), plus memory the compressor has squeezed out of residency (compressed), counts. Clean, read-only, or shared memory (like code pages loaded from system libraries) doesn't, no matter how much RAM it occupies. The exact formula, from the XNU kernel source (osfmk/kern/task.c):

phys_footprint = (internal - alternate_accounting)
                + (internal_compressed - alternate_accounting_compressed)
                + iokit_mapped
                + purgeable_nonvolatile
                + purgeable_nonvolatile_compressed
                + page_table

Why this metric: it's the same number Xcode's memory gauge shows, and the one Jetsam actually uses to decide whether to kill your app, so it's the most actionable measure of your app's real memory risk.

Further reading

How Android memory footprint is calculated

Android has no single official "memory footprint" metric; the term covers three different measurements. Per the Android memory management guide:

  • Resident Set Size (RSS): The number of shared and non-shared pages used by the app
  • Proportional Set Size (PSS): The number of non-shared pages used by the app and an even distribution of the shared pages (for example, if three processes are sharing 3MB, each process gets 1MB in PSS)
  • Unique Set Size (USS): The number of non-shared pages used by the app (shared pages are not included)

getMemoryFootprint() reports anonymous RSS + swap: resident anonymous memory (heap, native allocations, thread stacks) plus anonymous memory currently swapped out. It's read directly from RssAnon + VmSwap in /proc/self/status, a single cheap file read with no special permissions needed.

Why this metric: it's the same one behind Play Console's "excessive memory usage" vitals warning, per the Play Vitals memory usage doc:

Tracking anonymous RSS + swap ensures you see your app's true, unevictable memory footprint.

It's also a better match for actual kill risk than PSS. PSS's proportional-sharing math exists for system-wide RAM bookkeeping, not for judging whether your app individually is heavy, and Android's low-memory killer daemon doesn't use PSS either: per the AOSP lmkd source, it picks a victim by reading plain RSS from /proc/pid/statm. Anonymous RSS + swap sits close to that, while also mirroring iOS's "dirty + compressed" model.

Further reading

Contributing

License

MIT


Made with create-react-native-library