From 58a21d3471abc3aea66c538f4d698188b7c8e7bb Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Fri, 28 Mar 2025 15:09:21 +0200
Subject: [PATCH 01/14] feat: add nitro view template

---
 .../common/$.github/workflows/ci.yml          |  4 +--
 .../templates/common/$package.json            | 10 +++----
 .../templates/common/CONTRIBUTING.md          |  4 ++-
 .../templates/common/README.md                |  8 ++++--
 .../native-common/android/build.gradle        | 16 +++++------
 .../native-common/{%- project.name %}.podspec |  2 +-
 .../nitro-view/android/CMakeLists.txt         | 24 ++++++++++++++++
 .../android/src/main/cpp/cpp-adapter.cpp      |  6 ++++
 .../{%- project.name %}.kt                    | 23 +++++++++++++++
 .../{%- project.name %}Package.kt             | 28 +++++++++++++++++++
 .../nitro-view/ios/{%- project.name %}.swift  | 28 +++++++++++++++++++
 .../templates/nitro-view/nitro.json           | 17 +++++++++++
 .../templates/nitro-view/src/index.tsx        |  8 ++++++
 .../src/{%- project.name %}.nitro.ts          | 12 ++++++++
 14 files changed, 171 insertions(+), 19 deletions(-)
 create mode 100644 packages/create-react-native-library/templates/nitro-view/android/CMakeLists.txt
 create mode 100644 packages/create-react-native-library/templates/nitro-view/android/src/main/cpp/cpp-adapter.cpp
 create mode 100644 packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt
 create mode 100644 packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt
 create mode 100644 packages/create-react-native-library/templates/nitro-view/ios/{%- project.name %}.swift
 create mode 100644 packages/create-react-native-library/templates/nitro-view/nitro.json
 create mode 100644 packages/create-react-native-library/templates/nitro-view/src/index.tsx
 create mode 100644 packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts

diff --git a/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml b/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml
index 3cba52f1..9e791972 100644
--- a/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml
+++ b/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml
@@ -61,7 +61,7 @@ jobs:
 
       - name: Setup
         uses: ./.github/actions/setup
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
 
       - name: Generate nitrogen code
         run: yarn nitrogen
@@ -122,7 +122,7 @@ jobs:
 
       - name: Setup
         uses: ./.github/actions/setup
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
 
       - name: Generate nitrogen code
         run: yarn nitrogen
diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json
index cd773f35..32bfb613 100644
--- a/packages/create-react-native-library/templates/common/$package.json
+++ b/packages/create-react-native-library/templates/common/$package.json
@@ -52,7 +52,7 @@
     "clean": "del-cli lib",
 <% } -%>
     "prepare": "bob build",
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
     "nitrogen": "nitro-codegen",
 <% } -%>
     "release": "release-it"
@@ -91,14 +91,14 @@
     "eslint-config-prettier": "^9.0.0",
     "eslint-plugin-prettier": "^5.0.1",
     "jest": "^29.7.0",
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
     "nitro-codegen": "^<%- versions.nitroCodegen %>",
 <% } -%>
     "prettier": "^3.0.3",
     "react": "17.0.2",
     "react-native": "0.73.0",
     "react-native-builder-bob": "^<%- versions.bob %>",
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
     "react-native-nitro-modules": "^<%- versions.nitroModules %>",
 <% } -%>
     "release-it": "^17.10.0",
@@ -112,7 +112,7 @@
   },
   "peerDependencies": {
     "react": "*",
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
     "react-native": "*",
     "react-native-nitro-modules": "^<%- versions.nitroModules %>"
 <% } else { -%>
@@ -191,7 +191,7 @@
     "source": "src",
     "output": "lib",
     "targets": [
-<% if (project.moduleConfig === "nitro-modules") { -%>
+<% if (project.moduleConfig === "nitro-modules" || project.viewConfig === "nitro-view") { -%>
       [
         "custom",
         {
diff --git a/packages/create-react-native-library/templates/common/CONTRIBUTING.md b/packages/create-react-native-library/templates/common/CONTRIBUTING.md
index fa78e872..85cdcf56 100644
--- a/packages/create-react-native-library/templates/common/CONTRIBUTING.md
+++ b/packages/create-react-native-library/templates/common/CONTRIBUTING.md
@@ -18,13 +18,14 @@ yarn
 ```
 
 > Since the project relies on Yarn workspaces, you cannot use [`npm`](https://github.com/npm/cli) for development.
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+> <% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
 
 This project uses Nitro Modules. If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/).
 
 You need to run [Nitrogen](https://nitro.margelo.com/docs/nitrogen) to generate the boilerplate code required for this project. The example app will not build without this step.
 
 Run **Nitrogen** in following cases:
+
 - When you make changes to any `*.nitro.ts` files.
 - When running the project for the first time (since the generated files are not committed to the repository).
 
@@ -33,6 +34,7 @@ To invoke **Nitrogen**, use the following command:
 ```sh
 yarn nitrogen
 ```
+
 <% } -%>
 
 The [example app](/example/) demonstrates usage of the library. You need to run it to test any changes you make.
diff --git a/packages/create-react-native-library/templates/common/README.md b/packages/create-react-native-library/templates/common/README.md
index 5b34c58f..aacb0cf3 100644
--- a/packages/create-react-native-library/templates/common/README.md
+++ b/packages/create-react-native-library/templates/common/README.md
@@ -4,16 +4,20 @@
 
 ## Installation
 
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
+
 ```sh
 npm install <%- project.slug %> react-native-nitro-modules
 
 > `react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/).
 ```
+
 <% } else { -%>
+
 ```sh
 npm install <%- project.slug %>
 ```
+
 <% } -%>
 
 ## Usage
@@ -28,7 +32,7 @@ import { <%- project.name -%>View } from "<%- project.slug -%>";
 <<%- project.name -%>View color="tomato" />
 ```
 
-<% } else if (project.moduleConfig === 'nitro-modules' || project.moduleConfig === 'turbo-modules') { -%>
+<% } else if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view' || project.moduleConfig === 'turbo-modules') { -%>
 
 ```js
 import { multiply } from '<%- project.slug -%>';
diff --git a/packages/create-react-native-library/templates/native-common/android/build.gradle b/packages/create-react-native-library/templates/native-common/android/build.gradle
index d7925a44..fa3912ca 100644
--- a/packages/create-react-native-library/templates/native-common/android/build.gradle
+++ b/packages/create-react-native-library/templates/native-common/android/build.gradle
@@ -15,7 +15,7 @@ buildscript {
   }
 }
 
-<% if (project.cpp || project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.cpp || project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
 def reactNativeArchitectures() {
   def value = rootProject.getProperties().get("reactNativeArchitectures")
   return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
@@ -24,7 +24,7 @@ def reactNativeArchitectures() {
 
 apply plugin: "com.android.library"
 apply plugin: "kotlin-android"
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
 apply from: '../nitrogen/generated/android/<%- project.package_cpp -%>+autolinking.gradle'
 <% } -%>
 
@@ -47,7 +47,7 @@ def supportsNamespace() {
 
 android {
   if (supportsNamespace()) {
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
     namespace "com.margelo.nitro.<%- project.package -%>"
 <% } else { -%>
     namespace "com.<%- project.package -%>"
@@ -68,7 +68,7 @@ android {
   defaultConfig {
     minSdkVersion getExtOrIntegerDefault("minSdkVersion")
     targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
-<% if (project.cpp || project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.cpp || project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
 
     externalNativeBuild {
       cmake {
@@ -88,7 +88,7 @@ android {
     }
 <% } -%>
   }
-<% if (project.cpp || project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.cpp || project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
 
   externalNativeBuild {
     cmake {
@@ -96,7 +96,7 @@ android {
     }
   }
 <% } -%>
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
 
   packagingOptions {
     excludes = [
@@ -123,7 +123,7 @@ android {
 
   buildFeatures {
     buildConfig true
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
     prefab true
 <% } -%>
   }
@@ -166,7 +166,7 @@ def kotlin_version = getExtOrDefault("kotlinVersion")
 dependencies {
   implementation "com.facebook.react:react-android"
   implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
-<% if (project.moduleConfig === 'nitro-modules') { -%>
+<% if (project.moduleConfig === 'nitro-modules' || project.viewConfig === 'nitro-view') { -%>
   implementation project(":react-native-nitro-modules")
 <% } -%>
 }
diff --git a/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec
index 1c440cfb..5327b690 100644
--- a/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec	
+++ b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec	
@@ -23,7 +23,7 @@ Pod::Spec.new do |s|
 <% } else { -%>
   s.source_files = "ios/**/*.{h,m,mm}"
 <% } -%>
-<% if (project.moduleConfig === "nitro-modules") { -%>
+<% if (project.moduleConfig === "nitro-modules" || project.viewConfig === "nitro-view") { -%>
 
   load 'nitrogen/generated/ios/<%- project.name -%>+autolinking.rb'
   add_nitrogen_files(s)
diff --git a/packages/create-react-native-library/templates/nitro-view/android/CMakeLists.txt b/packages/create-react-native-library/templates/nitro-view/android/CMakeLists.txt
new file mode 100644
index 00000000..1fa9ed39
--- /dev/null
+++ b/packages/create-react-native-library/templates/nitro-view/android/CMakeLists.txt
@@ -0,0 +1,24 @@
+project(<%- project.package_cpp -%>)
+cmake_minimum_required(VERSION 3.9.0)
+
+set(PACKAGE_NAME <%- project.package_cpp -%>)
+set(CMAKE_VERBOSE_MAKEFILE ON)
+set(CMAKE_CXX_STANDARD 20)
+
+# Define C++ library and add all sources
+add_library(${PACKAGE_NAME} SHARED src/main/cpp/cpp-adapter.cpp)
+
+# Add Nitrogen specs :)
+include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/<%- project.package_cpp -%>+autolinking.cmake)
+
+# Set up local includes
+include_directories("src/main/cpp" "../cpp")
+
+find_library(LOG_LIB log)
+
+# Link all libraries together
+target_link_libraries(
+        ${PACKAGE_NAME}
+        ${LOG_LIB}
+        android # <-- Android core
+)
diff --git a/packages/create-react-native-library/templates/nitro-view/android/src/main/cpp/cpp-adapter.cpp b/packages/create-react-native-library/templates/nitro-view/android/src/main/cpp/cpp-adapter.cpp
new file mode 100644
index 00000000..8e1f6123
--- /dev/null
+++ b/packages/create-react-native-library/templates/nitro-view/android/src/main/cpp/cpp-adapter.cpp
@@ -0,0 +1,6 @@
+#include <jni.h>
+#include "<%- project.package_cpp -%>OnLoad.hpp"
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
+  return margelo::nitro::<%- project.package_cpp -%>::initialize(vm);
+}
diff --git a/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt b/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt
new file mode 100644
index 00000000..9634f8d5
--- /dev/null
+++ b/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt	
@@ -0,0 +1,23 @@
+package com.margelo.nitro.<%- project.package %>
+
+import android.view.View
+import com.facebook.proguard.annotations.DoNotStrip
+import com.facebook.react.uimanager.ThemedReactContext
+import androidx.core.graphics.toColorInt
+
+@DoNotStrip
+class Hybrid<%- project.name %>(val context: ThemedReactContext) : Hybrid<%- project.name %>Spec() {
+
+  // View
+  override val view: View = View(context)
+
+  // Props
+  private var _color = "#000"
+  override var color: String
+      get() = _color
+      set(value) {
+          _color = value
+          val color = value.toColorInt()
+          view.setBackgroundColor(color)
+      }
+}
diff --git a/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt b/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt
new file mode 100644
index 00000000..c2ceba5a
--- /dev/null
+++ b/packages/create-react-native-library/templates/nitro-view/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt	
@@ -0,0 +1,28 @@
+package com.<%- project.package %>
+
+import com.facebook.react.TurboReactPackage
+import com.facebook.react.bridge.NativeModule
+import com.facebook.react.bridge.ReactApplicationContext
+import com.facebook.react.module.model.ReactModuleInfoProvider
+import com.facebook.react.uimanager.ViewManager
+import com.margelo.nitro.<%- project.package_cpp -%>.views.Hybrid<%- project.name -%>Manager
+
+class <%- project.name -%>Package : TurboReactPackage() {
+    override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
+        return null
+    }
+
+    override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
+        return ReactModuleInfoProvider { HashMap() }
+    }
+
+    override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
+        return listOf(Hybrid<%- project.name -%>Manager())
+    }
+
+    companion object {
+        init {
+            System.loadLibrary("<%- project.package_cpp -%>")
+        }
+    }
+}
diff --git a/packages/create-react-native-library/templates/nitro-view/ios/{%- project.name %}.swift b/packages/create-react-native-library/templates/nitro-view/ios/{%- project.name %}.swift
new file mode 100644
index 00000000..0e4c8ef3
--- /dev/null
+++ b/packages/create-react-native-library/templates/nitro-view/ios/{%- project.name %}.swift	
@@ -0,0 +1,28 @@
+class Hybrid<%- project.name -%> : Hybrid<%- project.name -%>Spec {
+
+  // UIView
+  var view: UIView = UIView()
+
+  // props
+  var color: String = "#000" {
+    didSet {
+      view.backgroundColor = hexStringToUIColor(hexColor: color)
+    }
+  }
+  
+  func hexStringToUIColor(hexColor: String) -> UIColor {
+    let stringScanner = Scanner(string: hexColor)
+
+    if(hexColor.hasPrefix("#")) {
+      stringScanner.scanLocation = 1
+    }
+    var color: UInt32 = 0
+    stringScanner.scanHexInt32(&color)
+
+    let r = CGFloat(Int(color >> 16) & 0x000000FF)
+    let g = CGFloat(Int(color >> 8) & 0x000000FF)
+    let b = CGFloat(Int(color) & 0x000000FF)
+
+    return UIColor(red: r / 255.0, green: g / 255.0, blue: b / 255.0, alpha: 1)
+  }  
+}
diff --git a/packages/create-react-native-library/templates/nitro-view/nitro.json b/packages/create-react-native-library/templates/nitro-view/nitro.json
new file mode 100644
index 00000000..78941a51
--- /dev/null
+++ b/packages/create-react-native-library/templates/nitro-view/nitro.json
@@ -0,0 +1,17 @@
+{
+  "cxxNamespace": ["<%- project.package_cpp -%>"],
+  "ios": {
+    "iosModuleName": "<%- project.name -%>"
+  },
+  "android": {
+    "androidNamespace": <%- JSON.stringify(project.package.split('.')) -%>,
+    "androidCxxLibName": "<%- project.package_cpp -%>"
+  },
+  "autolinking": {
+    "<%- project.name -%>": {
+      "swift": "Hybrid<%- project.name -%>",
+      "kotlin": "Hybrid<%- project.name -%>"
+    }
+  },
+  "ignorePaths": ["node_modules"]
+}
diff --git a/packages/create-react-native-library/templates/nitro-view/src/index.tsx b/packages/create-react-native-library/templates/nitro-view/src/index.tsx
new file mode 100644
index 00000000..67a42c92
--- /dev/null
+++ b/packages/create-react-native-library/templates/nitro-view/src/index.tsx
@@ -0,0 +1,8 @@
+import { getHostComponent } from 'react-native-nitro-modules';
+import <%- project.name %>Config from '../nitrogen/generated/shared/json/<%- project.name %>Config.json';
+import type { <%- project.name %>Methods, <%- project.name %>Props } from './<%- project.name %>.nitro';
+
+export const <%- project.name %>View = getHostComponent<<%- project.name %>Props, <%- project.name %>Methods>(
+  '<%- project.name %>',
+  () => <%- project.name %>Config
+);
diff --git a/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts b/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts
new file mode 100644
index 00000000..467dcf83
--- /dev/null
+++ b/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts	
@@ -0,0 +1,12 @@
+import type {
+  HybridView,
+  HybridViewMethods,
+  HybridViewProps,
+} from 'react-native-nitro-modules';
+
+export interface <%- project.name %>Props extends HybridViewProps {
+  color: string;
+}
+export interface <%- project.name %>Methods extends HybridViewMethods {}
+
+export type <%- project.name %> = HybridView<<%- project.name %>Props, <%- project.name %>Methods>;

From ce5ed31b70141abd4fed5fcebb02314f8e12513c Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Fri, 28 Mar 2025 15:30:54 +0200
Subject: [PATCH 02/14] chore: change nitro modules version to 0.25.2

---
 packages/create-react-native-library/src/index.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts
index f109da15..9f01610b 100644
--- a/packages/create-react-native-library/src/index.ts
+++ b/packages/create-react-native-library/src/index.ts
@@ -21,7 +21,7 @@ import { getDependencyVersionsFromExampleApp } from './exampleApp/dependencies';
 import { printErrorHelp, printNextSteps, printUsedRNVersion } from './inform';
 
 const FALLBACK_BOB_VERSION = '0.36.0';
-const FALLBACK_NITRO_MODULES_VERSION = '0.22.1';
+const FALLBACK_NITRO_MODULES_VERSION = '0.25.2';
 
 yargs
   .command(

From ba232d23874cb835713a28389e220b76785a01f0 Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Fri, 28 Mar 2025 15:31:47 +0200
Subject: [PATCH 03/14] feat: add nitro view to template creation

---
 .../src/exampleApp/generateExampleApp.ts               |  5 ++++-
 packages/create-react-native-library/src/index.ts      |  3 +--
 packages/create-react-native-library/src/input.ts      |  9 ++++++++-
 packages/create-react-native-library/src/template.ts   | 10 +++++++++-
 4 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts
index 457897fb..646a95ce 100644
--- a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts
+++ b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts
@@ -181,7 +181,10 @@ export default async function generateExampleApp({
     'react-native-builder-bob': `^${config.versions.bob}`,
   };
 
-  if (config.project.moduleConfig === 'nitro-modules') {
+  if (
+    config.project.moduleConfig === 'nitro-modules' ||
+    config.project.viewConfig === 'nitro-view'
+  ) {
     const packagesToAddNitro = {
       'react-native-nitro-modules': `^${config.versions.nitroModules}`,
     };
diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts
index 9f01610b..4ffbe12c 100644
--- a/packages/create-react-native-library/src/index.ts
+++ b/packages/create-react-native-library/src/index.ts
@@ -74,9 +74,8 @@ async function create(_argv: yargs.Arguments<Args>) {
   assertUserInput(questions, answers);
 
   const bobVersion = await bobVersionPromise;
-
   const nitroModulesVersion =
-    answers.type === 'nitro-module'
+    answers.type === 'nitro-module' || answers.type === 'nitro-view'
       ? await nitroModulesVersionPromise
       : undefined;
 
diff --git a/packages/create-react-native-library/src/input.ts b/packages/create-react-native-library/src/input.ts
index 3d9c8f88..73b9d3bc 100644
--- a/packages/create-react-native-library/src/input.ts
+++ b/packages/create-react-native-library/src/input.ts
@@ -26,6 +26,7 @@ export type ProjectType =
   | 'legacy-module'
   | 'legacy-view'
   | 'nitro-module'
+  | 'nitro-view'
   | 'library';
 
 const LANGUAGE_CHOICES: {
@@ -36,7 +37,7 @@ const LANGUAGE_CHOICES: {
   {
     title: 'Kotlin & Swift',
     value: 'kotlin-swift',
-    types: ['nitro-module', 'legacy-module', 'legacy-view'],
+    types: ['nitro-view', 'nitro-module', 'legacy-module', 'legacy-view'],
   },
   {
     title: 'Kotlin & Objective-C',
@@ -96,6 +97,12 @@ const TYPE_CHOICES: {
     description:
       'type-safe, fast integration for native APIs to JS (experimental)',
   },
+  {
+    title: 'Nitro View',
+    value: 'nitro-view',
+    description:
+      'integration for native views to JS using nitro for prop parsing (experimental)',
+  },
   {
     title: 'Fabric view',
     value: 'fabric-view',
diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts
index c003891c..b70fd75b 100644
--- a/packages/create-react-native-library/src/template.ts
+++ b/packages/create-react-native-library/src/template.ts
@@ -20,7 +20,7 @@ export type ModuleConfig =
   | 'nitro-modules'
   | null;
 
-export type ViewConfig = 'paper-view' | 'fabric-view' | null;
+export type ViewConfig = 'paper-view' | 'fabric-view' | 'nitro-view' | null;
 
 // Please think at least 5 times before introducing a new config key
 // You can just reuse the existing ones most of the time
@@ -90,6 +90,7 @@ const NATIVE_FILES = {
   view_legacy: path.resolve(__dirname, '../templates/native-view-legacy'),
   view_new: path.resolve(__dirname, '../templates/native-view-new'),
   module_nitro: path.resolve(__dirname, '../templates/nitro-module'),
+  view_nitro: path.resolve(__dirname, '../templates/nitro-view'),
 } as const;
 
 const OBJC_FILES = {
@@ -195,6 +196,8 @@ function getViewConfig(projectType: ProjectType): ViewConfig {
       return 'paper-view';
     case 'fabric-view':
       return 'fabric-view';
+    case 'nitro-view':
+      return 'nitro-view';
     default:
       return null;
   }
@@ -241,6 +244,11 @@ export async function applyTemplates(
       return;
     }
 
+    if (config.project.viewConfig === 'nitro-view') {
+      await applyTemplate(config, NATIVE_FILES['view_nitro'], folder);
+      return;
+    }
+
     if (config.project.moduleConfig !== null) {
       await applyTemplate(
         config,

From 82fdf09086c4859113668abc67217ee7a9d63708 Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Fri, 28 Mar 2025 15:35:46 +0200
Subject: [PATCH 04/14] feat: ios16 min deployment for nitro modules example
 app

---
 .../src/exampleApp/generateExampleApp.ts      | 70 +++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts
index 646a95ce..b71ff0c3 100644
--- a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts
+++ b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts
@@ -300,6 +300,76 @@ export default async function generateExampleApp({
       }
     }
 
+    // nitro modules on xcode 16.2 requires ios 16 version because of the bug https://github.com/swiftlang/swift/issues/77909
+    // full thread in https://github.com/mrousavy/nitro/issues/422
+    if (
+      config.project.viewConfig === 'nitro-view' ||
+      config.project.moduleConfig === 'nitro-modules'
+    ) {
+      const newTargetVersion = 16.0;
+
+      const podfile = await fs.readFile(
+        path.join(directory, 'ios', 'Podfile'),
+        'utf8'
+      );
+
+      const postInstallLine = 'post_install do |installer|';
+      // set pods deployement min version
+      const podVersionOverride = `
+    installer.pods_project.targets.each do |target|
+      target.build_configurations.each do |config|
+        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '${newTargetVersion}'
+      end
+    end
+    `;
+
+      const insertionIndex = podfile.indexOf(postInstallLine);
+
+      if (insertionIndex !== -1) {
+        const endOfMarkerLineIndex = podfile.indexOf('\n', insertionIndex);
+
+        if (endOfMarkerLineIndex !== -1) {
+          const updatedPodfileContent =
+            podfile.slice(0, endOfMarkerLineIndex) +
+            podVersionOverride +
+            podfile.slice(endOfMarkerLineIndex);
+
+          await fs.writeFile(
+            path.join(directory, 'ios', 'Podfile'),
+            updatedPodfileContent
+          );
+        }
+      }
+
+      // set project deployement min version
+      const project = await fs.readFile(
+        path.join(
+          directory,
+          `ios/${config.project.name}Example.xcodeproj`,
+          'project.pbxproj'
+        ),
+        'utf8'
+      );
+
+      // match whole IPHONEOS_DEPLOYMENT_TARGET line
+      const deployementLineRegex =
+        /^(\s*)IPHONEOS_DEPLOYMENT_TARGET\s*=\s*[^;]+;$/gm;
+      const replacementPattern = `$1IPHONEOS_DEPLOYMENT_TARGET = ${newTargetVersion};`;
+      const updatedContent = project.replace(
+        deployementLineRegex,
+        replacementPattern
+      );
+
+      await fs.writeFile(
+        path.join(
+          directory,
+          `ios/${config.project.name}Example.xcodeproj`,
+          'project.pbxproj'
+        ),
+        updatedContent
+      );
+    }
+
     await fs.writeFile(
       path.join(directory, 'android', 'gradle.properties'),
       gradleProperties

From 4595d45004bee5352ff607e2bafe9ecb5310a614 Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Fri, 28 Mar 2025 16:43:52 +0200
Subject: [PATCH 05/14] chore: remove autospace in readme


From f124db5f47a6f79895a636d6528548a1fdfef1ca Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Fri, 28 Mar 2025 16:45:11 +0200
Subject: [PATCH 06/14] chore: lower case Nitro view in selection

---
 packages/create-react-native-library/src/input.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/create-react-native-library/src/input.ts b/packages/create-react-native-library/src/input.ts
index 73b9d3bc..8311c025 100644
--- a/packages/create-react-native-library/src/input.ts
+++ b/packages/create-react-native-library/src/input.ts
@@ -98,7 +98,7 @@ const TYPE_CHOICES: {
       'type-safe, fast integration for native APIs to JS (experimental)',
   },
   {
-    title: 'Nitro View',
+    title: 'Nitro view',
     value: 'nitro-view',
     description:
       'integration for native views to JS using nitro for prop parsing (experimental)',

From 6e003c8e86338ee19458602a9ba17bdc259aae98 Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Mon, 31 Mar 2025 16:09:30 +0300
Subject: [PATCH 07/14] fix: add nitro view to CI matrix

---
 .github/workflows/build-templates.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/.github/workflows/build-templates.yml b/.github/workflows/build-templates.yml
index 73d5df0b..cf7a7435 100644
--- a/.github/workflows/build-templates.yml
+++ b/.github/workflows/build-templates.yml
@@ -35,6 +35,7 @@ jobs:
           - legacy-module
           - legacy-view
           - nitro-module
+          - nitro-view
         language:
           - kotlin-objc
           - kotlin-swift
@@ -52,6 +53,10 @@ jobs:
             language: kotlin-objc
           - type: nitro-module
             language: cpp
+          - type: nitro-view
+            language: kotlin-objc
+          - type: nitro-view
+            language: cpp
         include:
           - os: ubuntu
             type: library

From 46c4f897d01be68f5013c5de76d3b8365a33c29a Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Mon, 31 Mar 2025 16:18:55 +0300
Subject: [PATCH 08/14] fix: prettier ci error

---
 .../templates/nitro-view/src/{%- project.name %}.nitro.ts    | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts b/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts
index 467dcf83..2cbd723b 100644
--- a/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts	
+++ b/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts	
@@ -9,4 +9,7 @@ export interface <%- project.name %>Props extends HybridViewProps {
 }
 export interface <%- project.name %>Methods extends HybridViewMethods {}
 
-export type <%- project.name %> = HybridView<<%- project.name %>Props, <%- project.name %>Methods>;
+export type <%- project.name %> = HybridView<
+  <%- project.name %>Props,
+  <%- project.name %>Methods
+>;
\ No newline at end of file

From 14496f07d0e2868bf3985761876a93fe6aa9db58 Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Mon, 31 Mar 2025 17:28:23 +0300
Subject: [PATCH 09/14] fix: prettier formatting for CI

---
 .../templates/nitro-view/src/index.tsx              | 13 ++++++++-----
 .../nitro-view/src/{%- project.name %}.nitro.ts     |  2 +-
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/packages/create-react-native-library/templates/nitro-view/src/index.tsx b/packages/create-react-native-library/templates/nitro-view/src/index.tsx
index 67a42c92..e260bef1 100644
--- a/packages/create-react-native-library/templates/nitro-view/src/index.tsx
+++ b/packages/create-react-native-library/templates/nitro-view/src/index.tsx
@@ -1,8 +1,11 @@
 import { getHostComponent } from 'react-native-nitro-modules';
 import <%- project.name %>Config from '../nitrogen/generated/shared/json/<%- project.name %>Config.json';
-import type { <%- project.name %>Methods, <%- project.name %>Props } from './<%- project.name %>.nitro';
+import type {
+  <%- project.name %>Methods,
+  <%- project.name %>Props,
+} from './<%- project.name %>.nitro';
 
-export const <%- project.name %>View = getHostComponent<<%- project.name %>Props, <%- project.name %>Methods>(
-  '<%- project.name %>',
-  () => <%- project.name %>Config
-);
+export const <%- project.name %>View = getHostComponent<
+  <%- project.name %>Props,
+  <%- project.name %>Methods
+>('<%- project.name %>', () => <%- project.name %>Config);
diff --git a/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts b/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts
index 2cbd723b..194477f9 100644
--- a/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts	
+++ b/packages/create-react-native-library/templates/nitro-view/src/{%- project.name %}.nitro.ts	
@@ -12,4 +12,4 @@ export interface <%- project.name %>Methods extends HybridViewMethods {}
 export type <%- project.name %> = HybridView<
   <%- project.name %>Props,
   <%- project.name %>Methods
->;
\ No newline at end of file
+>;

From aa67b12dd6d7597fab06e4fd2b161391927ecafc Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Tue, 1 Apr 2025 17:18:45 +0300
Subject: [PATCH 10/14] fix: add nitrogen step in CI

---
 .github/workflows/build-templates.yml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/.github/workflows/build-templates.yml b/.github/workflows/build-templates.yml
index cf7a7435..41cd2a5b 100644
--- a/.github/workflows/build-templates.yml
+++ b/.github/workflows/build-templates.yml
@@ -152,6 +152,10 @@ jobs:
             fi
           fi
 
+      - name: Generate nitrogen code
+        if: matrix.type == 'nitro-view' || matrix.type == 'nitro-module' 
+        run: yarn nitrogen
+
       - name: Cache turborepo
         if: env.android_build == 1 || env.ios_build == 1
         uses: actions/cache@v4

From 02509386b744ecdaeab82df1f33202f251ccc10a Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Tue, 1 Apr 2025 17:25:43 +0300
Subject: [PATCH 11/14] fix: add full nitro-codegen command

---
 .github/workflows/build-templates.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/build-templates.yml b/.github/workflows/build-templates.yml
index 41cd2a5b..ea365c10 100644
--- a/.github/workflows/build-templates.yml
+++ b/.github/workflows/build-templates.yml
@@ -154,7 +154,7 @@ jobs:
 
       - name: Generate nitrogen code
         if: matrix.type == 'nitro-view' || matrix.type == 'nitro-module' 
-        run: yarn nitrogen
+        run: yarn nitro-codegen
 
       - name: Cache turborepo
         if: env.android_build == 1 || env.ios_build == 1

From 6ffc282e4eb5ca46ecd46dd5c22232a962a45967 Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Tue, 1 Apr 2025 17:32:19 +0300
Subject: [PATCH 12/14] fix: add working dir to nitrogen

---
 .github/workflows/build-templates.yml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/build-templates.yml b/.github/workflows/build-templates.yml
index ea365c10..53d1e1ce 100644
--- a/.github/workflows/build-templates.yml
+++ b/.github/workflows/build-templates.yml
@@ -153,8 +153,9 @@ jobs:
           fi
 
       - name: Generate nitrogen code
-        if: matrix.type == 'nitro-view' || matrix.type == 'nitro-module' 
-        run: yarn nitro-codegen
+        if: matrix.type == 'nitro-view' || matrix.type == 'nitro-module'
+        working-directory: ${{ env.work_dir }}
+        run: yarn nitrogen
 
       - name: Cache turborepo
         if: env.android_build == 1 || env.ios_build == 1

From e545ba33b45ea02338508e20feb11929cf366bed Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Fri, 4 Apr 2025 09:06:47 +0300
Subject: [PATCH 13/14] fix: change config json import to require

---
 .../templates/nitro-view/src/index.tsx                         | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/create-react-native-library/templates/nitro-view/src/index.tsx b/packages/create-react-native-library/templates/nitro-view/src/index.tsx
index e260bef1..6d2946c1 100644
--- a/packages/create-react-native-library/templates/nitro-view/src/index.tsx
+++ b/packages/create-react-native-library/templates/nitro-view/src/index.tsx
@@ -1,5 +1,6 @@
 import { getHostComponent } from 'react-native-nitro-modules';
-import <%- project.name %>Config from '../nitrogen/generated/shared/json/<%- project.name %>Config.json';
+// import <%- project.name %>Config from '../nitrogen/generated/shared/json/<%- project.name %>Config.json';
+const <%- project.name %>Config = require('../nitrogen/generated/shared/json/<%- project.name %>Config.json')
 import type {
   <%- project.name %>Methods,
   <%- project.name %>Props,

From 1a21f3b115e58c1c0c121ab8c19f9801d7e28f41 Mon Sep 17 00:00:00 2001
From: Juozas Petkelis <juozas.petkelis@callstack.com>
Date: Fri, 4 Apr 2025 09:20:36 +0300
Subject: [PATCH 14/14] chore: prettier fix

---
 .../templates/nitro-view/src/index.tsx                         | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/packages/create-react-native-library/templates/nitro-view/src/index.tsx b/packages/create-react-native-library/templates/nitro-view/src/index.tsx
index 6d2946c1..2f1c9526 100644
--- a/packages/create-react-native-library/templates/nitro-view/src/index.tsx
+++ b/packages/create-react-native-library/templates/nitro-view/src/index.tsx
@@ -1,6 +1,5 @@
 import { getHostComponent } from 'react-native-nitro-modules';
-// import <%- project.name %>Config from '../nitrogen/generated/shared/json/<%- project.name %>Config.json';
-const <%- project.name %>Config = require('../nitrogen/generated/shared/json/<%- project.name %>Config.json')
+const <%- project.name %>Config = require('../nitrogen/generated/shared/json/<%- project.name %>Config.json');
 import type {
   <%- project.name %>Methods,
   <%- project.name %>Props,