$npx -y skills add margelo/react-native-skills --skill build-nitro-modulesBuilds and designs React Native Nitro Modules with Nitrogen, HybridObject TypeScript specs, Nitro View components, generated native implementations, zero-copy and native-state APIs, Swift/Kotlin/C++ bindings, example apps, and testing. Use when creating a Nitro Module, adding or
| 1 | # Build Nitro Modules |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | End-to-end skill for building a React Native Nitro Module: monorepo scaffolding via Nitrogen, TypeScript HybridObject spec authoring, native code generation, platform implementation (C++/Swift/Kotlin), example app wiring, and publish preparation. |
| 6 | |
| 7 | Nitro Modules use a codegen pipeline (`nitrogen`) that reads `.nitro.ts` spec files and generates native C++/Swift/Kotlin boilerplate. You then fill in the implementation. This is fundamentally different from old-style turbo modules. |
| 8 | |
| 9 | Generated files under `nitrogen/generated/` are outputs. Change the `.nitro.ts` spec or native implementation source, then re-run nitrogen instead of manually editing generated files. These files can be committed to git, and many Nitro libraries do commit them, but the repo policy can choose otherwise. They must be included in the npm package so consumers can build the native library. |
| 10 | |
| 11 | ## Pair With API Design |
| 12 | |
| 13 | Use `api-design` first when shaping the public TypeScript, JavaScript, React, or React Native API. This skill adds the Nitro-specific constraints: HybridObject state, generated specs, native resource ownership, zero-copy data, threading, platform implementation, codegen, and real-device validation. |
| 14 | |
| 15 | Let `api-design` own general public API rules and API freshness checks. In this skill, only add Nitro-specific freshness checks for mobile toolchain and generated-template decisions: verify current Nitro, React Native, Gradle, Xcode, Swift, Kotlin, NDK, and package-tooling docs/source before choosing versions, config fields, or native implementation details. |
| 16 | |
| 17 | If the user is building a JS-only React or React Native library, do not apply this skill unless Nitro, HybridObjects, native modules, codegen, C++/Swift/Kotlin bindings, or `react-native-nitro-modules` are part of the task. |
| 18 | |
| 19 | Pair with `swift` when implementing or reviewing Swift-backed HybridObjects, AVFoundation/session code, DispatchQueue usage, Swift concurrency, or thread-affine Swift state. Pair with `kotlin` when implementing or reviewing Kotlin-backed HybridObjects, Android threading, coroutines, Kotlin nullability, sealed result models, or Android service access. Pair with `cpp` when implementing or reviewing C++-backed HybridObjects, shared native engines, CMake, RAII ownership, or generated C++ spec bindings. |
| 20 | |
| 21 | ## Repo and Release References |
| 22 | |
| 23 | Load [repo-structure-and-workflow.md][repo-structure-and-workflow] only when creating a repo, reorganizing layout, adding examples/docs/CI, or changing workflow policy. |
| 24 | |
| 25 | Load [release-it-publishing.md][release-it-publishing] only when setting up or reviewing `bun release` / `release-it`. |
| 26 | |
| 27 | ## Nitro API Design Rules |
| 28 | |
| 29 | - Prefer Nitro Modules over TurboModules or handwritten JSI for native module work. Nitro is usually faster and safer because it avoids many raw JSI lifetime, threading, and runtime-destruction hazards. Use raw JSI only when Nitro's Raw JSI Methods are required. |
| 30 | - Keep the root HybridObject default-constructible for autolinking. Create argument-dependent objects through factory methods. |
| 31 | - Use HybridObjects for native state: native resources, prewarmed engines, files, images, databases, sensor sessions, streams, and other stateful objects. |
| 32 | - If native setup is required, make the factory method async and resolve with a ready HybridObject, such as `createCameraSession(...): Promise<CameraSession>`. |
| 33 | - One JS-facing HybridObject spec can have multiple native concrete classes implementing the generated spec. Use this to hide backend strategies behind one TypeScript type, for example `CameraVideoOutput` backed by either a movie-file output or a video-data-output plus asset writer. Factories choose the native implementation and return the shared spec type. |
| 34 | - Use a product/domain noun for the exported JS factory object, not the generated spec type name. For example, export `VisionCamera = createHybridObject<CameraFactory>('CameraFactory')` or `Images = createHybridObject<ImageFactory>('ImageFactory')`. This avoids collisions with `CameraFactory`/`ImageFactory` types without mechanically lowercasing them or adding `Hybrid` prefixes. |
| 35 | - Keep each HybridObject scoped to one purpose or lifecycle. |
| 36 | - Do not choose HybridObject boundaries only by domain noun. A one-shot command |