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-monty

v0.8.0

Published

Nitro Modules bridge for Monty on iOS, Android, and web

Readme

react-native-monty

Run Python code on iOS, Android, and the web from React Native.

react-native-monty embeds Monty, a sandboxed Python interpreter written in Rust, and exposes it through a single TypeScript API. On native platforms the interpreter runs as compiled Rust via FFI; on the web it falls back to an embedded WASM binary. Your app ships the same code everywhere.

Features

  • Cross-platform -- iOS (Swift FFI), Android (JNI), and web (WASM) behind one API
  • Sandboxed execution -- resource limits on allocations, memory, time, and recursion depth
  • External functions -- call JavaScript functions from Python and vice versa
  • Pausable / resumable -- execution yields at external function calls, letting you inspect state, run async work, then resume
  • Serializable snapshots -- dump and restore execution state as Uint8Array for persistence or transfer
  • Type checking -- optional static type checking with rich diagnostics
  • Async support -- runMontyAsync handles external functions that return promises

Quick start

npm install react-native-monty
# or
yarn add react-native-monty
import { loadMonty, Monty } from "react-native-monty";

// Load the runtime (required on web, no-op on native)
await loadMonty();

const monty = new Monty("x + y", {
  scriptName: "add.py",
  inputs: ["x", "y"],
});

const result = monty.run({ inputs: { x: 2, y: 5 } });
// result === 7

External functions

Python code can call into your JavaScript functions. Define them at run time and they are available inside the script:

const monty = new Monty(
  "def run(value):\n    return multiply_and_add(value, 10)\n\nrun(input_value)",
  { scriptName: "external.py", inputs: ["input_value"] },
);

const output = monty.run({
  inputs: { input_value: 2 },
  externalFunctions: {
    multiply_and_add: (value, factor) => Number(value) * Number(factor) + 7,
  },
});
// output === 27

Async external functions

If your external functions need to do async work (network requests, database calls, etc.), use runMontyAsync:

import { runMontyAsync, Monty } from "react-native-monty";

const monty = new Monty("fetch_data(url)", {
  inputs: ["url"],
});

const result = await runMontyAsync(monty, {
  inputs: { url: "https://example.com/data" },
  externalFunctions: {
    fetch_data: async (url) => {
      const res = await fetch(String(url));
      return await res.text();
    },
  },
});

Pausable execution

For fine-grained control, use start / resume to step through execution manually:

import { Monty, MontySnapshot, MontyComplete } from "react-native-monty";

const monty = new Monty("result = compute(42)");
let progress = monty.start();

while (progress instanceof MontySnapshot) {
  console.log(`Python called: ${progress.functionName}(${progress.args})`);
  const returnValue = handleCall(progress.functionName, progress.args);
  progress = progress.resume({ returnValue });
}

// progress is now MontyComplete
console.log(progress.output);

Snapshots are serializable -- call snapshot.dump() to persist state and MontySnapshot.load(data) to restore it later.

Resource limits

Constrain execution to prevent runaway scripts:

monty.run({
  limits: {
    maxDurationSecs: 5,
    maxMemory: 10 * 1024 * 1024, // 10 MB
    maxAllocations: 100_000,
    maxRecursionDepth: 50,
  },
});

API reference

Classes

| Class | Description | |---|---| | Monty | Compile a script and run or start execution | | MontySnapshot | Paused execution state at an external function call | | MontyComplete | Completed execution with .output | | MontyRepl | Interactive REPL session (web only) | | MontyError | Base error class | | MontySyntaxError | Parse-time errors | | MontyRuntimeError | Runtime exceptions with .traceback() | | MontyTypingError | Static type-check errors with .displayDiagnostics() |

Functions

| Function | Description | |---|---| | loadMonty() | Load the WASM runtime (required on web, no-op on native) | | runMontyAsync(monty, options) | Run with async external functions | | montyExpoVersion() | Package version string | | montyExpoNativeRuntimeLinked() | Whether native FFI is available |

Architecture

TypeScript API (src/index.ts)
  │
  ├─ Native ──▶ Nitro Modules bridge ──▶ Rust FFI (native/monty-expo-ffi)
  │               iOS: Swift ──▶ C FFI
  │               Android: Kotlin ──▶ JNI
  │
  └─ Web ──▶ Embedded WASM runtime (src/web/monty/)

All cross-language communication uses JSON serialization. The Rust FFI layer handles type mapping between Python objects and JSON, including special types like big integers, bytes, tuples, sets, dataclasses, and named tuples.

Build from source

# Full build (web + rust + codegen + typescript)
yarn build

# Or step by step:
yarn build:web           # Download and compile WASM from upstream
yarn build:rust          # Compile Rust FFI for iOS + Android
yarn codegen             # Generate Nitro Modules native bindings
yarn build:ts            # TypeScript compilation

The web runtime is built from the pinned upstream ref in package.json (config.montyUpstreamRef, currently v0.0.8). Override for one-off builds:

MONTY_UPSTREAM_REF=<tag-or-commit> yarn build:web

Platform-specific Rust builds:

yarn build:rust:ios
yarn build:rust:android

License

MIT