diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml
new file mode 100644
index 0000000000..2f32679ade
--- /dev/null
+++ b/.github/workflows/build-windows.yml
@@ -0,0 +1,79 @@
+name: Build Windows
+
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - '.github/workflows/build-windows.yml'
+ - 'packages/react-native-nitro-modules/cpp/**'
+ - 'packages/react-native-nitro-modules/windows/**'
+ - '**/react-native.config.js'
+ pull_request:
+ paths:
+ - '.github/workflows/build-windows.yml'
+ - 'packages/react-native-nitro-modules/cpp/**'
+ - 'packages/react-native-nitro-modules/windows/**'
+ - '**/react-native.config.js'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ name: Build NitroModules.vcxproj
+ runs-on: windows-2022
+ steps:
+ - uses: actions/checkout@v5
+
+ - uses: actions/setup-node@v6
+ with:
+ node-version: 20
+
+ - name: Add MSBuild to PATH
+ uses: microsoft/setup-msbuild@v2
+
+ - name: Set up a react-native-windows consumer
+ shell: pwsh
+ run: |
+ New-Item -ItemType Directory -Force -Path consumer | Out-Null
+ Set-Location consumer
+ npm init -y | Out-Null
+ npm install --no-audit --no-fund `
+ react-native@${{ env.RN_VERSION }} `
+ react-native-windows@${{ env.RNW_VERSION }}
+ env:
+ RN_VERSION: 0.84.1
+ RNW_VERSION: 0.84.0
+
+ - name: Restore NuGet packages
+ shell: pwsh
+ run: |
+ msbuild packages/react-native-nitro-modules/windows/NitroModules/NitroModules.vcxproj `
+ /t:Restore `
+ /p:Configuration=Debug `
+ /p:Platform=x64 `
+ /p:RnwNewArch=true `
+ /p:ReactNativeWindowsDir=$(Resolve-Path consumer/node_modules/react-native-windows)\
+
+ - name: Build (Debug|x64)
+ shell: pwsh
+ run: |
+ msbuild packages/react-native-nitro-modules/windows/NitroModules/NitroModules.vcxproj `
+ /p:Configuration=Debug `
+ /p:Platform=x64 `
+ /p:RnwNewArch=true `
+ /p:ReactNativeWindowsDir=$(Resolve-Path consumer/node_modules/react-native-windows)\ `
+ /verbosity:minimal `
+ /warnaserror:C4715,C4700
+
+ - name: Build (Release|x64)
+ shell: pwsh
+ run: |
+ msbuild packages/react-native-nitro-modules/windows/NitroModules/NitroModules.vcxproj `
+ /p:Configuration=Release `
+ /p:Platform=x64 `
+ /p:RnwNewArch=true `
+ /p:ReactNativeWindowsDir=$(Resolve-Path consumer/node_modules/react-native-windows)\ `
+ /verbosity:minimal
diff --git a/docs/docs/getting-started/minimum-requirements.md b/docs/docs/getting-started/minimum-requirements.md
index 30135f494b..1cad13ff36 100644
--- a/docs/docs/getting-started/minimum-requirements.md
+++ b/docs/docs/getting-started/minimum-requirements.md
@@ -1,5 +1,5 @@
---
-description: Check the React Native, iOS, Android, Swift, Kotlin, Gradle, and C++ requirements needed to use Nitro Modules.
+description: Check the React Native, iOS, Android, Windows, Swift, Kotlin, Gradle, and C++ requirements needed to use Nitro Modules.
---
import Tabs from '@theme/Tabs';
@@ -21,4 +21,9 @@ To use Nitro, make sure your app meets the minimum requirements:
- `compileSdkVersion` 34 or higher
- `ndkVersion` 27 or higher
+
+ - react-native-windows 0.78 or higher (`ReactContext::CallInvoker()` was added in 0.78)
+ - Visual Studio 2022 with the "Desktop development with C++" workload (toolset v143)
+ - Hybrid Objects must be implemented in C++ - see [Windows](../guides/windows.md)
+
diff --git a/docs/docs/guides/windows.md b/docs/docs/guides/windows.md
new file mode 100644
index 0000000000..f95f844e7f
--- /dev/null
+++ b/docs/docs/guides/windows.md
@@ -0,0 +1,166 @@
+---
+sidebar_position: 9
+---
+
+# Windows
+
+Nitro runs on [react-native-windows](https://microsoft.github.io/react-native-windows/) (RNW).
+Hybrid Objects are written in **C++** there - Windows has no equivalent of the Swift and
+Kotlin bridges, so `HybridObject<{ windows: 'c++' }>` is the only supported form:
+
+```ts
+export interface Math extends HybridObject<{ ios: 'c++', android: 'c++', windows: 'c++' }> {
+ add(a: number, b: number): number
+}
+```
+
+The C++ specs nitrogen generates are shared with iOS and Android, so an existing
+C++ Hybrid Object usually needs nothing more than adding `windows: 'c++'` to its
+platform spec.
+
+## Installing
+
+```sh
+npm i react-native-nitro-modules
+npx @react-native-community/cli autolink-windows
+```
+
+Autolinking adds `NitroModules.vcxproj` to your app's solution, references it from
+your app project, and appends Nitro's package provider to
+`windows//AutolinkedNativeModules.g.cpp`.
+
+Two settings your app project needs, both because Nitro is a C++20 static library:
+
+```xml
+
+
+
+ false
+
+
+
+
+
+ stdcpp20
+
+
+```
+
+## Adding Windows to a Nitro Module
+
+Point your module's `.vcxproj` at the property sheet nitrogen generates, and give
+react-native-windows the package provider it generates:
+
+```xml
+
+
+```
+
+```js
+// react-native.config.js
+module.exports = {
+ dependency: {
+ platforms: {
+ windows: {
+ sourceDir: 'windows',
+ projects: [
+ {
+ projectFile: 'MyModule\\MyModule.vcxproj',
+ directDependency: true,
+ cppHeaders: ['MyModuleAutolinking.hpp'],
+ cppPackageProviders: ['MyModule::ReactPackageProvider'],
+ },
+ ],
+ },
+ },
+ },
+}
+```
+
+Your `.vcxproj` also needs a `ProjectReference` to `NitroModules.vcxproj`, which is
+what puts Nitro's headers on your include path:
+
+```xml
+
+
+ {c6e3e6e4-3d5f-4c0b-9a5e-5d2c1b9f7a10}
+
+
+```
+
+The `winrt::` namespace of the generated `ReactPackageProvider` comes from
+`windows.windowsModuleName` in [`nitro.json`](../getting-started/configuration-nitro-json.md),
+and falls back to `ios.iosModuleName` when it isn't set.
+
+## How Nitro installs itself
+
+Nitro is installed from a two-argument `REACT_INIT` on the `NitroModules` module:
+
+```cpp
+void Initialize(ReactContext const& context, facebook::jsi::Runtime& runtime) noexcept;
+```
+
+react-native-windows dispatches this through `AddJsiInitializer` on the JS thread,
+which is the only JSI entry-point that still works once the New Architecture
+(`RnwNewArch=true`) is enabled - `ExecuteJsi`, `TryGetOrCreateContextRuntime` and
+`ReactContext::JSRuntime` are deprecated there and either fail-fast in Debug or
+silently do nothing in Release. Nitro's `Dispatcher` is backed by
+`ReactContext::CallInvoker()`, so callbacks and Promises land on the JS thread.
+
+## Things to know
+
+**Nitro links statically.** `NitroModules.vcxproj` is a `StaticLibrary`, not the DLL
+that RNW modules normally are. RNW hands every module image its own `JsiAbiRuntime`
+wrapper around the JS runtime, so Nitro in a separate DLL would see a different
+`jsi::Runtime*` than the Hybrid Objects linked into the app - and Nitro's `JSICache`,
+`PropNameIDCache` and `Dispatcher` are all keyed on the runtime, while
+`HybridObjectRegistry` has to be a single registry. Building into the app binary is
+what keeps them unique, so Nitro Modules should be static libraries too.
+
+**JSI calls cross an ABI boundary.** On Windows a native module never gets the raw
+Hermes runtime; every `jsi::` call goes through `JsiAbiRuntime`, a WinRT proxy inside
+`Microsoft.ReactNative.dll`. Nitro is still statically compiled and type-safe, but
+individual JSI operations cost more than they do on iOS and Android. Prefer batching
+work into fewer, larger calls.
+
+**`Dispatcher::runSync` is unavailable on the UI thread.** `IReactDispatcher` only
+exposes `Post`, so `UIThreadDispatcher::runSync()` throws - the same as on iOS.
+
+## Not yet supported
+
+- **Hybrid Views** - `HybridView` has no Windows implementation yet.
+- **`react-native-worklets`** - worklet contexts are not wired up on Windows.
+
+### Blocked on react-native-windows
+
+Two types are unusable in one direction because `JsiAbiRuntime` does not implement
+them. Both terminate the process rather than throwing, so avoid them in Windows
+Hybrid Objects until react-native-windows fixes them upstream.
+
+| | JS → native | native → JS |
+|---|---|---|
+| `bigint` (`int64_t`, `uint64_t`) | ❌ crashes | ✅ works |
+| `ArrayBuffer` | ✅ works | ❌ crashes |
+
+- **`bigint` arguments.** `JsiAbiRuntime::ValueRef::InitValueRef` allocates a
+ `PointerValue` for `Symbol`, `String` and `Object`, but `JsiValueKind::BigInt`
+ falls through to its `default:` branch and copies the raw ABI handle into the
+ `jsi::Value`'s pointer field. The first dereference - `asBigInt()` - is then an
+ access violation. Returning a `bigint` to JS takes a different path
+ (`JsiAbiRuntime::MakeValue`) that handles it correctly.
+- **Returning an `ArrayBuffer`.** `JsiAbiRuntime::createArrayBuffer` is an
+ unimplemented stub that calls `VerifyElseCrash(false)`. Reading and mutating a
+ buffer that JS allocated works, because `data()` and `size()` are implemented.
+
+`JsiAbiRuntime::setExternalMemoryPressure` is also an empty body, so the GC
+pressure a Hybrid Object reports through `getExternalMemorySize()` is ignored on
+Windows.
diff --git a/docs/sidebars.ts b/docs/sidebars.ts
index 6d70fd8db1..04f081d0bb 100644
--- a/docs/sidebars.ts
+++ b/docs/sidebars.ts
@@ -43,6 +43,7 @@ const sidebars: SidebarsConfig = {
'guides/entry-point',
'guides/sync-vs-async',
'guides/view-components',
+ 'guides/windows',
'guides/troubleshooting',
'guides/running-example-app',
]
diff --git a/packages/nitrogen/src/autolinking/createWindowsAutolinking.ts b/packages/nitrogen/src/autolinking/createWindowsAutolinking.ts
new file mode 100644
index 0000000000..b56a698e9a
--- /dev/null
+++ b/packages/nitrogen/src/autolinking/createWindowsAutolinking.ts
@@ -0,0 +1,21 @@
+import type { SourceFile } from '../syntax/SourceFile.js'
+import type { Autolinking } from './Autolinking.js'
+import { createHybridObjectIntializer } from './windows/createHybridObjectInitializer.js'
+import { createMsBuildExtension } from './windows/createMsBuildExtension.js'
+
+interface WindowsAutolinking extends Autolinking {}
+
+export function createWindowsAutolinking(
+ allFiles: SourceFile[]
+): WindowsAutolinking {
+ const hybridObjectInitializer = createHybridObjectIntializer()
+ const msBuildExtension = createMsBuildExtension(
+ allFiles,
+ hybridObjectInitializer.length > 0
+ )
+
+ return {
+ platform: 'windows',
+ sourceFiles: [msBuildExtension, ...hybridObjectInitializer],
+ }
+}
diff --git a/packages/nitrogen/src/autolinking/windows/createHybridObjectInitializer.ts b/packages/nitrogen/src/autolinking/windows/createHybridObjectInitializer.ts
new file mode 100644
index 0000000000..699205f27c
--- /dev/null
+++ b/packages/nitrogen/src/autolinking/windows/createHybridObjectInitializer.ts
@@ -0,0 +1,130 @@
+import { NitroConfig } from '../../config/NitroConfig.js'
+import { createCppHybridObjectRegistration } from '../../syntax/c++/CppHybridObjectRegistration.js'
+import { includeHeader } from '../../syntax/c++/includeNitroHeader.js'
+import { createFileMetadataString } from '../../syntax/helpers.js'
+import type { SourceFile, SourceImport } from '../../syntax/SourceFile.js'
+import { indent } from '../../utils.js'
+
+type CppFile = Omit & { language: 'c++' }
+
+export function getWindowsAutolinkingClassName(): string {
+ return `${NitroConfig.current.getWindowsModuleName()}Autolinking`
+}
+
+export function createHybridObjectIntializer(): [CppFile, CppFile] | [] {
+ const autolinkingClassName = getWindowsAutolinkingClassName()
+ const moduleName = NitroConfig.current.getWindowsModuleName()
+
+ const autolinkedHybridObjects =
+ NitroConfig.current.getAutolinkedHybridObjects()
+
+ const cppRegistrations: string[] = []
+ const cppImports: SourceImport[] = []
+ for (const hybridObjectName of Object.keys(autolinkedHybridObjects)) {
+ const implementation =
+ NitroConfig.current.getWindowsAutolinkedImplementation(hybridObjectName)
+ if (implementation == null) {
+ continue
+ }
+
+ if (implementation.language !== 'c++') {
+ throw new Error(
+ `The HybridObject "${hybridObjectName}" cannot be autolinked on Windows - Language "${implementation.language}" is not supported on Windows! ` +
+ `Only "c++" is supported on Windows.`
+ )
+ }
+
+ const { cppCode, requiredImports } = createCppHybridObjectRegistration({
+ hybridObjectName: hybridObjectName,
+ cppClassName: implementation.implementationClassName,
+ })
+ cppImports.push(...requiredImports)
+ cppRegistrations.push(cppCode)
+ }
+
+ if (cppRegistrations.length === 0) {
+ // Nothing to autolink!
+ return []
+ }
+
+ const imports = cppImports.map((i) => includeHeader(i, true)).join('\n')
+
+ const headerCode = `
+${createFileMetadataString(`${autolinkingClassName}.hpp`)}
+
+#pragma once
+
+#include
+
+namespace winrt::${moduleName} {
+
+/**
+ * Creates the \`IReactPackageProvider\` that registers all of ${moduleName}'s Hybrid Objects.
+ *
+ * Add this to your \`react-native.config.js\` so react-native-windows' autolinking
+ * calls it for you:
+ * \`\`\`js
+ * cppHeaders: ['${autolinkingClassName}.hpp'],
+ * cppPackageProviders: ['${moduleName}::ReactPackageProvider'],
+ * \`\`\`
+ */
+winrt::Microsoft::ReactNative::IReactPackageProvider ReactPackageProvider();
+
+} // namespace winrt::${moduleName}
+ `.trim()
+
+ const cppCode = `
+${createFileMetadataString(`${autolinkingClassName}.cpp`)}
+
+#include "${autolinkingClassName}.hpp"
+
+#include "HybridObjectRegistry.hpp"
+
+${imports}
+
+#include
+#include
+#include
+
+namespace winrt::${moduleName} {
+
+namespace {
+
+struct ${autolinkingClassName} : winrt::implements<${autolinkingClassName}, winrt::Microsoft::ReactNative::IReactPackageProvider> {
+ void CreatePackage(winrt::Microsoft::ReactNative::IReactPackageBuilder const& /* packageBuilder */) noexcept {
+ static std::once_flag registerOnce;
+ std::call_once(registerOnce, []() {
+ using namespace margelo::nitro;
+ using namespace ${NitroConfig.current.getCxxNamespace('c++')};
+
+ ${indent(cppRegistrations.join('\n'), ' ')}
+ });
+ }
+};
+
+} // namespace
+
+winrt::Microsoft::ReactNative::IReactPackageProvider ReactPackageProvider() {
+ return winrt::make<${autolinkingClassName}>();
+}
+
+} // namespace winrt::${moduleName}
+ `.trim()
+
+ return [
+ {
+ content: headerCode,
+ language: 'c++',
+ name: `${autolinkingClassName}.hpp`,
+ platform: 'windows',
+ subdirectory: [],
+ },
+ {
+ content: cppCode,
+ language: 'c++',
+ name: `${autolinkingClassName}.cpp`,
+ platform: 'windows',
+ subdirectory: [],
+ },
+ ]
+}
diff --git a/packages/nitrogen/src/autolinking/windows/createMsBuildExtension.ts b/packages/nitrogen/src/autolinking/windows/createMsBuildExtension.ts
new file mode 100644
index 0000000000..b602152f6f
--- /dev/null
+++ b/packages/nitrogen/src/autolinking/windows/createMsBuildExtension.ts
@@ -0,0 +1,101 @@
+import { NitroConfig } from '../../config/NitroConfig.js'
+import {
+ createFileMetadataString,
+ isCppFile,
+ isNotDuplicate,
+} from '../../syntax/helpers.js'
+import type { SourceFile } from '../../syntax/SourceFile.js'
+import { indent } from '../../utils.js'
+import { getWindowsAutolinkingClassName } from './createHybridObjectInitializer.js'
+
+export interface MsBuildFile extends Omit {
+ language: 'msbuild'
+}
+
+function toWindowsPath(path: string): string {
+ return path.replace(/\//g, '\\')
+}
+
+function generatedPath(...segments: string[]): string {
+ return '$(NitrogenGeneratedDir)' + toWindowsPath(segments.join('/'))
+}
+
+function getGeneratedPath(file: SourceFile): string {
+ return generatedPath(
+ file.platform,
+ file.language,
+ ...file.subdirectory,
+ file.name
+ )
+}
+
+export function createMsBuildExtension(
+ files: SourceFile[],
+ hasAutolinkedHybridObjects: boolean
+): MsBuildFile {
+ const name = NitroConfig.current.getWindowsModuleName()
+ const autolinkingClassName = getWindowsAutolinkingClassName()
+
+ const sourceFiles = files
+ .filter((f) => f.platform === 'shared' && isCppFile(f))
+ .map((f) => getGeneratedPath(f))
+ .filter(isNotDuplicate)
+
+ if (hasAutolinkedHybridObjects) {
+ sourceFiles.push(generatedPath('windows', `${autolinkingClassName}.cpp`))
+ }
+
+ const clCompiles = sourceFiles
+ .map((f) => ``)
+ .join('\n')
+
+ const code = `
+
+
+
+
+ $(MSBuildThisFileDirectory)..\\
+
+
+ $(NitrogenGeneratedDir)shared\\c++;
+ $(NitrogenGeneratedDir)windows;
+ $(PublicIncludeDirectories)
+
+
+
+
+
+ $(NitrogenGeneratedDir)shared\\c++;$(NitrogenGeneratedDir)windows;%(AdditionalIncludeDirectories)
+
+ stdcpp20
+ %(AdditionalOptions) /bigobj
+ Sync
+
+
+
+
+
+ ${indent(clCompiles, ' ')}
+
+
+ `.trim()
+
+ return {
+ content: code,
+ language: 'msbuild',
+ name: `${name}+autolinking.props`,
+ platform: 'windows',
+ subdirectory: [],
+ }
+}
diff --git a/packages/nitrogen/src/config/NitroConfig.ts b/packages/nitrogen/src/config/NitroConfig.ts
index 658d2eee2e..bef3c2f80a 100644
--- a/packages/nitrogen/src/config/NitroConfig.ts
+++ b/packages/nitrogen/src/config/NitroConfig.ts
@@ -4,6 +4,7 @@ import type {
AutolinkingAndroidImplementation,
AutolinkingIOSImplementation,
AutolinkingPlatformImplementation,
+ AutolinkingWindowsImplementation,
NitroUserConfig,
} from './NitroUserConfig.js'
@@ -50,6 +51,18 @@ export class NitroConfig {
return this.config.ios.iosModuleName
}
+ /**
+ * Returns the Windows module name of the module that will be generated.
+ * This is the `winrt::` namespace of the generated autolinking `ReactPackageProvider`.
+ * Falls back to the iOS module name if `windows` is not configured.
+ * @example `NitroTest`
+ */
+ getWindowsModuleName(): string {
+ return (
+ this.config.windows?.windowsModuleName ?? this.config.ios.iosModuleName
+ )
+ }
+
/**
* Represents the C++ namespace of the module that will be generated.
* This can have multiple sub-namespaces, and is always relative to `margelo::nitro`.
@@ -157,6 +170,19 @@ export class NitroConfig {
return objectConfig.android
}
+ getWindowsAutolinkedImplementation(
+ hybridObjectName: string
+ ): AutolinkingWindowsImplementation | undefined {
+ const objectConfig = this.config.autolinking[hybridObjectName]
+ if (objectConfig == null) {
+ return undefined
+ }
+ if (objectConfig.all != null) {
+ return objectConfig.all
+ }
+ return objectConfig.windows
+ }
+
/**
* Get the paths that will be ignored when loading the TypeScript project.
* In most cases, this just contains `node_modules/`.
diff --git a/packages/nitrogen/src/config/NitroUserConfig.ts b/packages/nitrogen/src/config/NitroUserConfig.ts
index a82b8e74c1..b46bfcea1d 100644
--- a/packages/nitrogen/src/config/NitroUserConfig.ts
+++ b/packages/nitrogen/src/config/NitroUserConfig.ts
@@ -26,6 +26,11 @@ const autolinkingAndroidImplementationSchema = z.object({
implementationClassName: z.string(),
})
+const autolinkingWindowsImplementationSchema = z.object({
+ language: z.literal('c++'),
+ implementationClassName: z.string(),
+})
+
const autolinkingPlatformImplementationSchema = z.object({
language: autolinkingLanguageSchema,
implementationClassName: z.string(),
@@ -36,6 +41,7 @@ const autolinkingModernHybridObjectSchema = z
all: autolinkingAllImplementationSchema.optional(),
ios: autolinkingIOSImplementationSchema.optional(),
android: autolinkingAndroidImplementationSchema.optional(),
+ windows: autolinkingWindowsImplementationSchema.optional(),
})
.catchall(autolinkingPlatformImplementationSchema)
.superRefine((value, ctx) => {
@@ -133,6 +139,9 @@ export type AutolinkingIOSImplementation = z.infer<
export type AutolinkingAndroidImplementation = z.infer<
typeof autolinkingAndroidImplementationSchema
>
+export type AutolinkingWindowsImplementation = z.infer<
+ typeof autolinkingWindowsImplementationSchema
+>
export type AutolinkingPlatformImplementation = z.infer<
typeof autolinkingPlatformImplementationSchema
>
@@ -201,6 +210,28 @@ export const NitroUserConfigSchema = z.object({
.regex(safeNamePattern)
.refine(isNotReservedKeyword, isReservedKeywordError),
}),
+ /**
+ * Windows specific options.
+ *
+ * This is optional - if it is omitted, {@linkcode ios.iosModuleName} is used as the
+ * Windows module name as well.
+ */
+ windows: z
+ .object({
+ /**
+ * Represents the Windows module name of the module that will be generated.
+ *
+ * This is the `winrt::` namespace nitrogen puts the generated autolinking
+ * `ReactPackageProvider` in, and the name of the generated MSBuild `.props` file.
+ * It should match the `` of your `.vcxproj`.
+ * @example `NitroTest`
+ */
+ windowsModuleName: z
+ .string()
+ .regex(safeNamePattern)
+ .refine(isNotReservedKeyword, isReservedKeywordError),
+ })
+ .optional(),
/**
* Configures the code that gets generated for autolinking (registering)
* Hybrid Object constructors.
diff --git a/packages/nitrogen/src/getPlatformSpecs.ts b/packages/nitrogen/src/getPlatformSpecs.ts
index db78f28032..9ba41e6b5a 100644
--- a/packages/nitrogen/src/getPlatformSpecs.ts
+++ b/packages/nitrogen/src/getPlatformSpecs.ts
@@ -9,6 +9,7 @@ export type Language = Required[keyof PlatformSpec]
const platformLanguages: { [K in Platform]: Language[] } = {
ios: ['swift', 'c++'],
android: ['kotlin', 'c++'],
+ windows: ['c++'],
}
const allPlatforms = Object.keys(platformLanguages) as Platform[]
const allLanguages = Object.values(platformLanguages).flatMap((l) => l)
diff --git a/packages/nitrogen/src/nitrogen.ts b/packages/nitrogen/src/nitrogen.ts
index 3fe66d57a6..5707ac99f0 100644
--- a/packages/nitrogen/src/nitrogen.ts
+++ b/packages/nitrogen/src/nitrogen.ts
@@ -22,6 +22,7 @@ import { Logger } from './Logger.js'
import { NitroConfig } from './config/NitroConfig.js'
import { createIOSAutolinking } from './autolinking/createIOSAutolinking.js'
import { createAndroidAutolinking } from './autolinking/createAndroidAutolinking.js'
+import { createWindowsAutolinking } from './autolinking/createWindowsAutolinking.js'
import type { Autolinking } from './autolinking/Autolinking.js'
import { createGitAttributes } from './createGitAttributes.js'
import type { PlatformSpec } from 'react-native-nitro-modules'
@@ -203,6 +204,9 @@ export async function runNitrogen({
if (usedPlatforms.includes('android')) {
autolinkingFiles.push(createAndroidAutolinking(writtenFiles))
}
+ if (usedPlatforms.includes('windows')) {
+ autolinkingFiles.push(createWindowsAutolinking(writtenFiles))
+ }
for (const autolinking of autolinkingFiles) {
Logger.info(
diff --git a/packages/nitrogen/src/syntax/SourceFile.ts b/packages/nitrogen/src/syntax/SourceFile.ts
index 3ce072ff24..339118347d 100644
--- a/packages/nitrogen/src/syntax/SourceFile.ts
+++ b/packages/nitrogen/src/syntax/SourceFile.ts
@@ -72,7 +72,7 @@ export interface SourceImport {
type GroupedFiles = Record
export function groupByPlatform(files: SourceFile[]): GroupedFiles {
- const result: GroupedFiles = { shared: [], ios: [], android: [] }
+ const result: GroupedFiles = { shared: [], ios: [], android: [], windows: [] }
for (const file of files) {
result[file.platform].push(file)
}
diff --git a/packages/react-native-nitro-modules/cpp/core/AnyMap.cpp b/packages/react-native-nitro-modules/cpp/core/AnyMap.cpp
index bad74084aa..0e20e87f37 100644
--- a/packages/react-native-nitro-modules/cpp/core/AnyMap.cpp
+++ b/packages/react-native-nitro-modules/cpp/core/AnyMap.cpp
@@ -3,6 +3,8 @@
//
#include "AnyMap.hpp"
+#include
+#include
namespace margelo::nitro {
diff --git a/packages/react-native-nitro-modules/cpp/core/AnyMap.hpp b/packages/react-native-nitro-modules/cpp/core/AnyMap.hpp
index 8aaf16137f..520c3eea0c 100644
--- a/packages/react-native-nitro-modules/cpp/core/AnyMap.hpp
+++ b/packages/react-native-nitro-modules/cpp/core/AnyMap.hpp
@@ -6,10 +6,12 @@
#include "NitroDefines.hpp"
#include "Null.hpp"
+#include
#include