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

bundo-appgen

v0.0.10

Published

Native app generator for React Native macOS

Readme

bundo-appgen

Generate native app project for React Native app host easily with a single JavaScript configuration, and a CLI.

Table of Contents

Requirements

  • Node.js v22 or latest
  • macOS
    • XcodeGen latest version for macOS .xcodeproj generator. You can install XcodeGen with Homebrew
    • Ruby v3 or latest
    • CocoaPods dependency manager
  • (Optional) tsx if you want to use TypeScript configuration for bundo-appgen

Technically, you can use Bun, but bundo-appgen is depending on Node.js Permission Model for bundo-appgen plugins. We may support for Bun fully until the permission model is supported. See Bun #6617 issue. You can still use Bun for local app development.

Installation

Install bundo-appgen in your project

Bun

bun install bundo-appgen

pnpm

pnpm install bundo-appgen

npm

npm install bundo-appgen

Fortunately, you can install bundo-appgen in your existing react-native-macos app, because bundo-appgen is a single independent package.

Usage

Configuration File

Create bundo.config.mjs file that lives beside of your package.json project

/**
 * @type {import("bundo-appgen").Config.Data}
 */
const config = {

  name: "Your App Name",

  macos: {
    bundleIdentifier: "com.yourcompany",
    buildVersion: "1",
    version: "1.0.0",
  },

}

export default config

TypeScript Configuration File

You can also use TypeScript config file, but you need tsx installed in your project as development dependency. Create bundo.config.mts or bundo.config.ts that lives beside of your package.json project

import {
  Config,
} from "bundo-appgen"

export default {

  name: "Your App Name",

  macos: {
    bundleIdentifier: "com.yourcompany",
    buildVersion: "1",
    version: "1.0.0",
  },

} satisfies Config.Data 

Explore other options in the Config.Data type definitions, such as changing app icon, app fonts, Info Plist, etc. We will provide a well documentation later regarding this. You can visit our development playground for your references.

Command Execution

bundo-appgen provides a command line interface to generate native project directory as a React Native app host. If you have experience with Expo Continuous Native Generation, this is really similar to the expo prebuild command.

:warning: If you are using bundo-appgen in your existing react-native-macos app, backup your entire project first, and remove the "macos" folder.

Now, generate your native app project by running this command

with Bun

bunx bundo-appgen

with pnpm

pnpx bundo-appgen

with npm

npx bundo-appgen

This command is doing these execution steps in order

  1. Retrieve and evaluate the configuration file
  2. Copy the native macos template from bundo-appgen to your project
  3. Modifying some files to the native template files, such as project renaming
  4. Run bundo-appgen plugin runner, and evaluating the result from plugins through IPC child process
  5. Modify some template files, because a plugin may want to customize it
  6. Execute xcodegen command to generate .xcodeproj directory

Now, you should see "macos" generated folder by the appgen command.

Run bunx bundo-appgen --help for more informations.

Running the App

Register your React entry with AppRegistry in your index.js file with "main" name

import {
  AppRegistry,
} from "react-native"

import App from "./App"

AppRegistry.registerComponent("main", () => App)

Finally, you can run Metro server bun run start, and run the app via Xcode.

You can also run your app with command

bunx react-native run-macos --scheme HelloWorld

The target name ("HelloWorld") is the .xcworkspace folder name without the .xcworkspace in the /macos directory.


Background

We want to wrap a native project as a React Native app host easily without hurting so much times by touching the native code or native platform tooling e.g. changing app icon, app metadata, touching native C++, Swift & Objective-C code for upgrading React Native, etc.

This package is heavily inspired by the Expo Continuous Native Generation. Expo does a heavy lifting that make developers focus more on providing and delivering the actual product.

bundo-appgen also wants to get the same experience like Expo, but bundo-appgen is supporting the macOS (and Windows probably in the future) that Expo does not want to, not creating another layer for native module e.g. Expo Modules, and sanboxed plugin for security reasons. Another differentiation is bundo-appgen providing bare platform configurations as much as possible and keeping each platform configurations separated. This is much easier for prototyping the native app project because each platform have some unique configurations that other platforms don't have, and we can follow each platform requirements much easier. For an example, you can see a configuration file example below

import {
  Config,
} from "bundo-appgen"

export default {
  
  // the `name` is shared, but overwriting through
  // the platform configuration is still possible,
  // e.g. CFBundleDisplayName in macOS Info.plist
  name: "Hello World App",

  macos: {

    appicon: "MyAppIcon",

    assetCatalog: {
      appiconset: [
        Config.Apple.createOSXappiconset({
          name: "MyAppIcon",
          images: {
            "1024x1024": "./path/to/your-image-1024.png",
            "512x512": "./path/to/your-image-512.png",
            "256x256": "./path/to/your-image-256.png",
            "128x128": "./path/to/your-image-128.png",
            "64x64": "./path/to/your-image-64.png",
            "32x32": "./path/to/your-image-32.png",
            "16x16": "./path/to/your-image-16.png",
          },
        }),
      ],
    },

    resources: [
      "./node_modules/ui-module/assets/fonts",
    ],
    infoPlist: {
      ATSApplicationFontsPath: "fonts/",
      NSMicrophoneUsageDescription: "We need to access your microphone, no questions!",
    },

    locales: ["en", "de"]

    stringCatalogs: {
      InfoPlist: {
        NSMicrophoneUsageDescription: {
          en: "We need to access your microphone, no questions!",
          de: "Wir mussen auf ihr Mikrofon zugreiefen, ohne Wenn und Aber!"
        },
      },
    }

  },

  windows: {
    // later
  },

  visionos: {
    // later
  },

  plugins: [],

} satisfies Config.Data

bundo-appgen is currently supporting macOS. Right after we are sure that our appgen (App Generator) for macOS is fully-ready-stabily, bundo-appgen will try to support the Windows platform, because it is really this project main plan at the time.

For Android and iOS, it is better to use Expo right now. It provides variety of first party packages in its ecosystem.

Sandboxed Plugin

Not to mention, bundo-appgen is also sandboxing the plugin invocation. We do not allow a plugin to perform an unrestricted action such as File System, Networking, Child Process, and other actions in Node.js. See Node.js Permission Model.

We only allow plugins to run their main function in restricted permission. Currently, we only allow this listed permission for plugin

  • File System - Read only access to these directories and/or files
    • <project>/macos/HelloWorld/AppDelegate.swift
    • <project>/macos/Podfile
    • node_modules directory lookup relatively from your project and global modules
    • Their own plugin directory

A plugin can still modify the templated files, such as AppDelegate.swift file for the macOS, but a plugin will only be allowed to modify in a manner way through a raw JavaScript string that bundo-appgen gives to their main function, instead of using file system to write. For your references, you can see our bundo-window plugin main function to modify the AppDelegate.swift to make the macOS app has no title bar.

We create a module that what we called "plugin runner". From the bundo-appgen command, it will spawn another Node.js child process with restricted permission to run the plugin runner. The plugin runner will invoke all the plugins main function provided with a JavaScript object (context) argument given. When all the plugin invocation have finished, we send the result to the main process through Inter Process Communication, and then, the main process will be responsible to do the actual writing to the template files.

We choose this model because we choose the Zero Trust approach. We do not want a plugin performs a malicious action in your machine with reading and writing to any directories (file system), networking, and spawning a child process.