From b1a4f626c0c23caad9675e8d58c8d3b62a37a38d Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 13 Aug 2026 07:29:07 +0000 Subject: [PATCH] docs: fill in HOW-IT-WORKS.md and CLI.md placeholders - HOW-IT-WORKS.md: replace the three TODO comments near the top with a real, runnable example of calculator-lib's native C addon (mirrors docs/USAGE.md) plus the JS that requires and calls it, and clone instructions for readers who want to follow along with the source referenced later in the document. - CLI.md: hand-write documentation for all five react-native-node-api CLI commands (vendor-hermes, link, list, info, patch-xcode-project), their options and the shared library-naming strategies, sourced from packages/host/src/node/cli/program.ts, hermes.ts and options.ts, with a note to keep it in sync with those definitions. Fixes #425 Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm --- docs/CLI.md | 66 +++++++++++++++++++++++++++++++++++++++++++- docs/HOW-IT-WORKS.md | 64 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 126 insertions(+), 4 deletions(-) diff --git a/docs/CLI.md b/docs/CLI.md index 9156480f..4282f403 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -1,3 +1,67 @@ # The `react-native-node-api` command-line interface (CLI) - +The `react-native-node-api` package installs a `react-native-node-api` binary, which app and library authors use to vendor Hermes, link Node-API modules into an app and inspect how the library-naming scheme resolves for a given module. + +```bash +npx react-native-node-api [options] +``` + +Run `npx react-native-node-api help` or `npx react-native-node-api help ` to see this same information from the CLI itself. + +> [!NOTE] +> This document is hand-written from the [Commander](https://github.com/tj/commander.js) program definition in [`packages/host/src/node/cli/program.ts`](../packages/host/src/node/cli/program.ts) (with the `vendor-hermes` command defined in [`hermes.ts`](../packages/host/src/node/cli/hermes.ts)). It needs to be kept in sync by hand whenever a command or its options change. + +## `vendor-hermes [from]` + +Clones the pinned commit of Hermes' `static_h` branch (which carries Hermes' first-party Node-API implementation) into the `sdks/node-api-hermes` directory of the app's `react-native` package, so the native build can compile against it. Prints the path to the vendored checkout on success. + +- `[from]` — Path to a file inside the app package. Defaults to the current working directory. +- `--react-native-package ` — The React Native package to vendor Hermes into. Defaults to `react-native`. +- `--silent` — Don't print anything except the final path. Defaults to `false`. +- `--force` — Don't check timestamps of input files to skip unnecessary rebuilds; removes and re-clones an existing checkout. Defaults to `false`. + +## `link [path]` + +Auto-links the Node-API modules found among the app's dependencies for one or more platforms, copying (and, on Apple, signing) them into place. + +- `[path]` — Some path inside the app package. Defaults to the current working directory. +- `--android` — Link Android modules. +- `--apple` — Link Apple modules. +- `--prune` — Delete previously vendored modules that are no longer auto-linked. Defaults to `true`. +- `--package-name ` — Controls how a dependency's package name is transformed into a library name. One of `strip`, `keep` or `omit` (see [Library naming](#library-naming) below). Defaults to `strip`, or the `NODE_API_PACKAGE_NAME` environment variable if set. +- `--path-suffix ` — Controls how the path of the addon inside a package is transformed into a library name. One of `strip`, `keep` or `omit` (see [Library naming](#library-naming) below). Defaults to `strip`, or the `NODE_API_PATH_SUFFIX` environment variable if set. + +At least one of `--android` / `--apple` must be passed, or the command exits with an error listing the supported platforms. + +## `list [from-path]` + +Lists the Node-API modules found among the dependencies of the package at (or above) a path, without linking them. + +- `[from-path]` — Some path inside the app package. Defaults to the current working directory. +- `--json` — Output the result as JSON instead of a human-readable summary. Defaults to `false`. +- `--package-name ` — Same as for `link` (see [Library naming](#library-naming)). +- `--path-suffix ` — Same as for `link` (see [Library naming](#library-naming)). + +## `info ` + +Utility to print the resolved module path, package name and computed library name for a single Node-API module, given its path. Useful for debugging naming collisions. + +- `` — Path to a Node-API module (e.g. an `*.android.node` directory or `*.apple.node` framework). +- `--package-name ` — Same as for `link` (see [Library naming](#library-naming)). +- `--path-suffix ` — Same as for `link` (see [Library naming](#library-naming)). + +## `patch-xcode-project [path]` + +Patches the app's Xcode project to add a build phase which copies, renames and signs the Node-API frameworks (equivalent to running `link --apple` as part of the Xcode build). Only supported on macOS. + +- `[path]` — Some path inside the app package. Defaults to the current working directory. + +## Library naming + +`--package-name` and `--path-suffix` both control how the [cross-platform library name](./PREBUILDS.md) (`package-name--path-component--addon-name`) is derived, and accept the same three strategies. Given a package `@my-org/my-pkg` with an addon at `build/Release/my-addon.node`: + +| Strategy | `--package-name` effect | `--path-suffix` effect | +| -------- | ----------------------------------------- | --------------------------------------------------- | +| `strip` | Scope is dropped: `my-pkg--my-addon` | Path is reduced to its basename: `my-pkg--my-addon` | +| `keep` | Scope is kept: `my-org--my-pkg--my-addon` | Full path is kept: `my-pkg--build-Release-my-addon` | +| `omit` | Package name is dropped: `my-addon` | Path is dropped: `my-pkg` | diff --git a/docs/HOW-IT-WORKS.md b/docs/HOW-IT-WORKS.md index 3a5167b3..edb0e0ac 100644 --- a/docs/HOW-IT-WORKS.md +++ b/docs/HOW-IT-WORKS.md @@ -2,9 +2,67 @@ This document will outline what happens throughout the various parts of the system, when the app calls the `add` method on the library introduced in the ["usage" document](./USAGE.md). - - - +If you want to follow along with the source code referenced throughout this document (such as `packages/host/cpp/HermesNapiHost.cpp`), clone this repo: + +```bash +git clone https://github.com/callstackincubator/react-native-node-api.git +``` + +`calculator-lib`'s native code is a small Node-API addon written in C (see the ["usage" document](./USAGE.md#implement-native-code) for the full walkthrough of writing and building it): + +```cpp +// addon.c + +#include +#include + +static napi_value Add(napi_env env, napi_callback_info info) { + napi_status status; + + size_t argc = 2; + napi_value args[2]; + status = napi_get_cb_info(env, info, &argc, args, NULL, NULL); + assert(status == napi_ok); + + double value0, value1; + status = napi_get_value_double(env, args[0], &value0); + assert(status == napi_ok); + status = napi_get_value_double(env, args[1], &value1); + assert(status == napi_ok); + + napi_value sum; + status = napi_create_double(env, value0 + value1, &sum); + assert(status == napi_ok); + + return sum; +} + +#define DECLARE_NAPI_METHOD(name, func) \ + { name, 0, func, 0, 0, 0, napi_default, 0 } + +NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) { + napi_status status; + + napi_property_descriptor addDescriptor = DECLARE_NAPI_METHOD("add", Add); + status = napi_define_properties(env, exports, 1, &addDescriptor); + assert(status == napi_ok); + + return exports; +} +``` + +`calculator-lib`'s JavaScript entrypoint requires the prebuilt binary produced from that C code: + +```javascript +module.exports = require("./prebuild.node"); +``` + +And `my-app` imports and calls it: + +```javascript +import { add } from "calculator-lib"; +console.log("1 + 2 =", add(1, 2)); +``` ## `my-app` makes an `import`