margelo/react-native-skillsMIT16 files

Build Nitro Modules

Builds 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 reviewing HybridObjects, building a Nitro View (HybridView) component, designing Nitro-specific public APIs, implementing native functionality, or setting up the nitrogen codegen pipeline. Pair with api-design for general library API shape.

Specification
Skill ID
margelo/react-native-skills/build-nitro-modules
Publisher
margelo
Repository
react-native-skills
Installs
0
Files
16
License
MIT
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

margelo/react-native-skills/build-nitro-modulesInstalls these files
  • SKILL.md
  • references/example-android-config.md
  • references/example-app-setup.md
  • references/example-metro-install.md
  • references/native-implement-cpp.md
  • references/native-implement-kotlin.md
  • references/native-implement-swift.md
  • references/native-nitrogen-codegen.md
  • references/release-it-publishing.md
  • references/repo-structure-and-workflow.md
  • references/setup-monorepo-init.md
  • references/spec-hybrid-object.md
  • references/spec-hybrid-view.md
  • references/spec-nitro-json.md
  • references/spec-package-publish.md
  • references/vision-camera-golden-standard.md

What this skill tells the agent

Build Nitro Modules

Overview

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.

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.

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.

Pair With API Design

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.

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.

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.

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.

Repo and Release References

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.

Load [release-it-publishing.md][release-it-publishing] only when setting up or reviewing bun release / release-it.

Nitro API Design Rules

  • 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.
  • Keep the root HybridObject default-constructible for autolinking. Create argument-dependent objects through factory methods.
  • Use HybridObjects for native state: native resources, prewarmed engines, files, images, databases, sensor sessions, streams, and other stateful objects.
  • If native setup is required, make the factory method async and resolve with a ready HybridObject, such as createCameraSession(...): Promise<CameraSession>.
  • 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.
  • 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.
  • Keep each HybridObject scoped to one purpose or lifecycle.
  • Do not choose HybridObject boundaries only by domain noun. A one-shot command, an app-owned live session, a native view, and a long-lived engine are different contracts even when they belong to the same feature area.
  • Split returned HybridObjects by stable semantic capability when their options, results, lifecycle, or future platform support differ. For example, a root DataScannerFactory can expose createBarcodeScanner() and createTextScanner() instead of one broad scanner whose text fields are nullable because Android currently supports only barcodes.
  • It is valid for a factory to report isTextScannerAvailable: false or reject createTextScanner() on platforms that do not support that capability today. Future platform support should fill in the existing capability and flip availability to true, not require redesigning a fat HybridObject.
  • Platform-specific capabilities can still be first-class HybridObjects when the concept is stable. For example, an iOS-only CameraObjectOutput can extend a shared CameraOutput, be marked @platform iOS, and reject at createObjectOutput(...) on Android instead of adding object-scanning nullable fields to every output.
  • Use factory methods to separate workflows and make returned HybridObjects stronger. If createLiveScanner() returns a live scanner session, baseline session operations that the implementation controls should be guaranteed by that type. Backends that cannot provide the live workflow should fail creation or return a narrower object, not force the live object to expose dead methods, nullable baseline properties, or repeated can* checks.
  • Return configured handles to avoid stale state. If configure(...) binds a device, output, stream, or native graph, return a new HybridObject handle for commands that only make sense for that configured resource. For example, a CameraSession.configure(...) method should return CameraController handles for setZoom(...) and focusTo(...) instead of putting those methods on CameraSession with implicit "current device" state.
  • Reconfiguration should replace or invalidate handles whose native target changed. Do not keep commands on a broad parent HybridObject when the command target depends on the last successful configuration.
  • For native negotiation, model requested intent separately from resolved state. Use ranked constraints or preferences as input, then return or emit a resolved config HybridObject/struct that describes what the session actually selected. Provide an explicit resolver method when callers need to preview the result without creating or starting the native session.
  • Use capability fields for workflow discovery, optional preferences, and genuinely variable support. Do not use capabilities to paper over an oversized HybridObject whose methods are unsupported during normal use on a supported backend.
  • Treat HybridObjects as primary API objects. Each primary HybridObject gets its own .nitro.ts file.
  • Keep an inheritance family in one .nitro.ts file only when the file is named after the base HybridObject and child HybridObjects add few or no members, such as ScannedCode, ScannedBarcode, and ScannedQRCode in ScannedCode.nitro.ts.
  • Put named codegen types in their own .ts files: string-literal unions/enums, structs/interfaces, option objects, event objects, callback option structs, and helper types. Nitro needs names for generated native structs and enum-like values. Import them into .nitro.ts specs and re-export public types from src/index.ts.

Use this skill in a project

Open any RiverX project, search the Skills panel for margelo/react-native-skills/build-nitro-modules, and install it in one click.

Use this skill