File: README.md
React Native for Windows
[Website](https://microsoft.github.io/react-native-windows) ยท [Documentation](https://microsoft.github.io/react-native-windows/docs/getting-started) ยท [Release notes](https://github.com/microsoft/react-native-windows/releases)
See the official React Native website for an introduction to React Native.
React Native is a framework developed by Meta that enables you to build world-class application experiences on native platforms using a consistent developer experience based on JavaScript and React. The focus of React Native is on developer efficiency across all the platforms you care about - learn once, write anywhere.
This repository adds support for the Windows 10 SDK, which allows you to build apps for all devices supported by Windows 10 including PCs, tablets, 2-in-1s, Xbox, Mixed reality devices etc.
Visit the official React Native for Windows + macOS website to learn more.
๐ฃ๏ธ Roadmap
Check out our blog if you'd like to stay up to date on the status of React Native for Windows and check out current and past roadmaps.
New Architecture
Fabric is the new rendering system for React Native, designed to share more rendering logic cross-platform. RNW's existing Paper renderer is built on UWP XAML, dropping down into native Composition as need be; the new RNW Fabric renderer targets Composition from the start but has the ability to host islands of XAML for advanced native controls. Apps on the new architecture will be WinAppSDK Win32 by default. For more details on our roadmap to Fabric, check out this pinned issue.
๐ผ๏ธ React Native Gallery
Make sure to also check out the React Native Gallery, our interactive sample experience showing everything you can do with React Native for Windows.
๐ Getting Started
See the Getting Started Guide on our React Native for Windows + macOS website to build your first React Native for Windows app.
Requirements
You can run React Native Windows apps only on devices supported by the Windows 10 SDK.
For a full and detailed list of the system requirements and how to set up your development platform, see our System Requirements documentation on our website.
Logging Issues
Search the existing issues and try to make sure your problem doesnโt already exist before opening a new issue. If your issue doesn't exist yet, provide as much information as possible so we can better help you. Include the information requested by the appropriate issue template.
Documentation
React Native has great documentation. React Native for Windows adds its own separate Windows and macOS documentation for desktop platform information like API docs and blog updates.
Examples
- Using the CLI in the Getting Started guide will set you up with a sample React Native for Windows app that you can begin editing right away.
- Check the samples repo for more standalone samples.
- The React Native Gallery app demonstrates various components in an interactive way.
- Check out the React Native Developer Blog to see examples from past conference talks, blog posts, and more.
- For more sample code browse the RNTester folder in the GitHub web UI.
๐ข Contributing
See Contributing guidelines for how to setup your fork of the repo and start a PR to contribute to React Native for Windows.
Not sure where to start? The good first issue and help wanted labels are the best starting points.
Code of Conduct
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
File: CodeQL.yml
This file is used to configure CodeQL alerts.
See https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/codeql/configuring-codeql3000-ado-pipelines#excluding-external-libraries-test-files-generated-files-docs
path_classifiers:
library:
- "/vnext/ReactCommon"
template:
- "/vnext/template"
- "/vnext/templates"
test:
# Explicitly include jest test paths
- "/flowtests"
- "/tests"
- "/src/e2etest"
- "/src/test"
# Explicitly include test projects
- "/packages/@office-iss/react-native-win32-tester"
- "/packages/@react-native/tester"
- "/packages/@react-native-windows/tester"
- "/packages/debug-test"
- "/packages/e2e-test-app-fabric"
- "/packages/integration-test-app"
- "/packages/playground"
- "/packages/sample-app-fabric"
- "/vnext/Desktop.IntegrationTests"
- "/vnext/Desktop.Test.DLL"
- "/vnext/Desktop.UnitTests"
- "/vnext/Microsoft.ReactNative.Cxx.UnitTests"
- "/vnext/Microsoft.ReactNative.IntegrationTests"
- "/vnext/Microsoft.ReactNative.Managed.CodeGen.UnitTests"
- "/vnext/Microsoft.ReactNative.Managed.UnitTests"
- "/vnext/Mso.UnitTests"
- "/vnext/ReactCommon.UnitTests"
- "/vnext/Test"
# Other explicit test includes
- "/packages/@office-iss/react-native-win32/IntegrationTests"
- "/packages/@office-iss/react-native-win32/src-win/IntegrationTests"
- "/vnext/IntegrationTests"
- "/vnext/ReactCopies/IntegrationTests"
- "/vnext/src-win/IntegrationTests"
File: CONTRIBUTING.md
Contributing to React Native for Windows
๐๐ First off, thanks for taking the time to contribute! ๐๐
Below is our guidance for how to report issues, propose new features, and submit contributions via Pull Requests (PRs).
๐ช Open Development Workflow
The React Native Windows team is VERY active in this GitHub Repo. In fact, we live in it all day long and carry out all our development in the open!
When the team finds issues we file them in the repo. When we propose new ideas or think-up new features, we file new feature requests. When we work on fixes or features, we create branches and work on those improvements. And when PRs are reviewed, we review in public - including all the good, the bad, and the ugly parts.
The point of doing all this work in public is to ensure that we are holding ourselves to a high degree of transparency, and so that the community sees that we apply the same processes and hold ourselves to the same quality-bar as we do to community-submitted issues and PRs.
To learn more about our approach to issue Triage, see "Triage Process" in our Wiki.
๐ค Repo Bot
The team triages new issues several times a week. During triage, the team uses labels to categorize, manage, and drive the project workflow.
We employ a bot engine to help us automate common processes within our workflow.
In the case that we need some additional information or changes to approve the PR, the triage team will mark the PR or Issue with label such as "Needs: Author Feedback". Keep an eye out for your GitHub notifications as the bot might automatically close your issue if it fails to recognize a response after some time. Should this happen to you, feel free to reactivate and provide the requested information.
Reporting Security Issues
Please do not report security vulnerabilities through public GitHub issues. Instead, please report them to the Microsoft Security Response Center (MSRC). See SECURITY.md for more information.
Before you start, file an issue
Please follow this simple rule to help us eliminate any unnecessary wasted effort & frustration, and ensure an efficient and effective use of everyone's time - yours, ours, and other community members':
๐ If you have a question, think you've discovered an issue, would like to propose a new feature, etc., then find/file an issue BEFORE starting work to fix/implement it.
Search existing issues first
Before filing a new issue, search existing open and closed issues first: This project is moving fast! It is likely someone else has found the problem you're seeing, and someone may be working on or have already contributed a fix!
If no existing item describes your issue/feature, great - please file a new issue:
File a new Issue
- Don't know whether you're reporting an issue or requesting a feature? File an issue
- Have a question that you don't see answered in docs, videos, etc.? File an issue
- Want to know if we're planning on building a particular feature? File an issue
- Got a great idea for a new feature? File an issue/request/idea
- Don't understand how to do something? File an issue
- Found an existing issue that describes yours? Great - upvote and add additional commentary / info / repro-steps / etc.
When you hit "New Issue", select the type of issue closest to what you want to report/ask/request to be prompted with the appropriate issue template.
Complete the template
Complete the information requested in the issue template, providing as much information as possible. The more information you provide, the more likely your issue/ask will be understood and implemented.
- We LOVE detailed repro steps! What steps do we need to take to reproduce the issue? Assume we love to read repro steps. As much detail as you can stand is probably barely enough detail for us!
- Prefer error message text where possible or screenshots of errors if text cannot be captured
- We MUCH prefer text command-line script than screenshots of command-line script.
- If you intend to implement the fix/feature yourself then say so! If you do not indicate otherwise we will assume that the issue is our to solve, or may label the issue as
Help-Wanted.
Contributing fixes / features
If you're able & willing to help fix issues and/or implement features, we'd love your contribution!
The best place to start is the list of "good first issue" issues. These are bugs or tasks that we on the team believe could be implemented for someone without any prior experience in the codebase. Once you're feeling more comfortable in the codebase, feel free to just use the "Help Wanted" label, or just find an issue your interested in and hop in!
Often, we like to assign issues that generally belong to somebody's area of expertise to the team member that owns that area. This doesn't mean the community can't jump in -- they should reach out and have a chat with the assignee to see if it'd okay to take. If an issue's been assigned more than a month ago, there's a good chance it's fair game to try yourself.
For a primer on our codebase, see "Repository Contents" and "Project Structure."
๐จโ๐ป Development
System Requirements: Contributing to this project requires a Windows machine, see rnw-dependencies for more info on this and the script for installing required dependencies.
๐ง Fork, Clone, Branch and Create your PR
As is standard for GitHub and open source projects, RNW uses the "Fork and pull" model for accepting and integrating code changes.
Here's what the contribution process looks like:
- Fork the repo if you haven't already.
- Clone your fork locally.
- Create & push a feature branch.
- Make the desired changes.
- Test your changes.
- Ensure your code passes linting checks:
- For C++ changes, you can run
yarn formatat the root of the repo to automatically reformat your code. - For JavaScript/TypeScript, you can run
yarn lint:fixat the root of the repo.
- For C++ changes, you can run
- After you've created your commits, make sure to run
yarn changeat the root of the repo to create "change files":- When prompted for
Change type, the first option (usuallyPrereleaseorPatch) is correct 99% of the time (don't selectNone). - When prompted to
Describe changes, please provide a descriptive message (defaults to your commit message). - The command will automatically create a new commit with the change files, make sure they're included in your PR.
- Note: You may be prompted multiple times or not at all (depending on which packages you modified).
- When prompted for
- Open a Pull Request (PR) and address any feedback.
๐ If this is your first time working with forks, you may find GitHub's reference on forks helpful. If this is your first time working with git or GitHub altogether, see the GitHub Quickstart guide for a walkthrough of setting up git, contributing to projects, and explanations of commonly used terms.
โ๏ธ For RNW-specific walkthrough on setting up your branch, see the Setup page in our Wiki.
๐ **Backporting**
There are cases when we'll want to port a fix back into one or more of the previous stable releases. If you are working on backporting a fix, your development process will look similar to what's described above, main difference being that your feature branch will need to build off of one of the n-stable branches as the base, instead of main. For example, if you were backporting a change to 0.67-stable you would run the following commands to get your branch set up:
> git fetch upstream
> git checkout 0.67-stable
> git pull upstream 0.67-stable
> git checkout -b backport_branch_nameThen once you've added and tested the desired changes, you'll have to make sure to specify the target stable branch, instead of main, as the base branch when creating your PR.
Note that in order to preserve stability and compatibility we don't backport all fixes, and all backport changes beyond a certain release (currently 0.66-stable) will go through additional triage to get approved.
For more information, see our Wiki page on Backporting.
๐งช Testing
Build and see if your solution works. Consult Building React-Native-Windows if you have problems.
Testing is a key component in the development workflow. If your changes affect existing test cases, or you're working on brand new features and also the accompanying test cases, see End-to-End Testing for more information about how to validate your work locally.
โ Code Review
When you'd like the team to review your PR, (even if the work is not yet fully-complete), open a PR so that the team can review your work and provide comments, suggestions, and request changes. It may take several cycles, but the end result will be solid, testable, conformant code that is safe for us to merge.
Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
๐ฅณ Merge
Once your code has been reviewed and approved by the team, it will be merged into the main branch. Once merged, your PR will be automatically closed.
๐ฆธ Thank you
Thank you in advance for your contribution! Now, what's next on the list? ๐
File: GuardianCustomConfiguration.json
{
"Enabled": false,
"Tools": {
"CredScan": {
"Inputs": {
"suppressionsFile": "$(Build.SourcesDirectory)/.ado/config/CredScanSuppressions.json"
}
}
},
"TSAOptions": {
"areaPath": "OS\Windows Client and Services\WinPD\SPICE\ReactNative",
"iterationPath": "OS\Future",
"notificationAliases": ["$(TSANotificationAliases)"],
"codebaseAdmins": ["$(TSACodebaseAdmins)"],
"bugTags": ["SDL", "Security"],
"instanceUrl": "https://dev.azure.com/microsoft",
"projectName": "OS",
"allTools": true
}
}
File: package.json
{
"name": "@rnw-scripts/react-native-windows-repo",
"version": "0.0.1",
"private": true,
"scripts": {
"build": "lage build",
"lint": "lage lint --verbose",
"lint:fix": "lage lint:fix",
"change": "beachball change",
"clean": "lage clean",
"doc": "doxysaurus --config vnext/doxysaurus.json",
"format": "format-files -i -style=file",
"format:verify": "format-files -i -style=file -verify",
"postinstall": "yarn build",
"release-notes": "yarn workspace @rnw-scripts/generate-release-notes release-notes",
"warm-feed": "yarn workspace @rnw-scripts/warm-feed warm-feed",
"spellcheck": "npx cspell",
"test": "lage test --verbose --passWithNoTests",
"validate-overrides": "react-native-platform-override validate",
"fork-sync": "node packages/@rnw-scripts/fork-sync/lib-commonjs/sync.js",
"fork-sync:status": "yarn fork-sync --dep fmt --status"
},
"repository": {
"type": "git",
"url": "[email protected]:microsoft/react-native-windows.git"
},
"license": "MIT",
"workspaces": {
"packages": [
"packages/",
"packages/@office-iss/",
"packages/@react-native-windows/",
"packages/@react-native/",
"packages/@rnw-scripts/",
"vnext"
]
},
"devDependencies": {
"@rnw-scripts/beachball-config": "0.0.0",
"@rnw-scripts/format-files": "",
"@rnw-scripts/integrate-rn": "",
"@rnw-scripts/just-task": "",
"@rnw-scripts/prepare-release": "",
"@rnw-scripts/promote-release": "",
"@rnw-scripts/stamp-version": "0.0.0",
"@rnw-scripts/take-screenshot": "",
"@rnw-scripts/unbroken": "",
"beachball": "^2.20.0",
"eslint": "^8.19.0",
"fast-glob": "^3.2.11",
"husky": "^4.2.5",
"lage": "^2.7.1",
"lodash": "^4.17.15",
"prettier": "^3.6.2",
"prettier-plugin-hermes-parser": "0.21.1",
"react": "19.2.3",
"react-native": "0.88.0-nightly-20260805-f2188610c",
"react-native-platform-override": "workspace:*",
"typescript": "5.1.6"
},
"resolutions": {
"react": "19.2.3",
"convert-source-map": "^2.0.0",
"kind-of": "6.0.3",
"glob-parent": "^5.1.2",
"node-notifier": "^9.0.0",
"safe-buffer": "^5.2.1",
"set-value": "^4.0.1",
"strip-ansi": "^6.0.1",
"parse-url/normalize-url": "^4.5.1",
"@react-native/monorepo/jest-junit": "^13.0.0",
"@react-native/monorepo/ws": "^6.2.3",
"@react-native/tester/ws": "^6.2.3",
"puppeteer-core/ws": "^8.17.1",
"form-data": "^4.0.6",
"@xmldom/xmldom": "^0.8.13",
"tmp": "^0.2.4",
"linkify-it": "^5.0.2",
"uuid": "^11.0.0",
"launch-editor": "^2.14.0",
"qs": "^6.15.0",
"ip-address": "10.3.1",
"@tootallnate/once": "^2.0.0",
"brace-expansion@^1.1.7": "^1.1.14",
"brace-expansion@^2.0.1": "^2.1.0",
"brace-expansion@^2.0.2": "^2.1.0",
"brace-expansion@^5.0.2": "^5.0.7",
"brace-expansion@^5.0.5": "^5.0.7",
"[email protected]": "^4.2.0",
"js-yaml@^4.0.0": "^4.2.0",
"js-yaml@^4.1.0": "^4.2.0",
"js-yaml@^4.1.1": "^4.2.0",
"js-yaml@^3.13.1": "^3.15.0",
"fast-xml-parser@^4.4.1": "^5.0.0",
"tar@^7.5.4": "^7.5.14",
"string_decoder": "portal:./packages/@rnw-scripts/shims/string_decoder"
},
"packageManager": "[email protected]"
}
File: sync-manifest.json
{
"version": 1,
"aiMerge": {
"provider": "claude",
"model": "haiku"
},
"dependencies": [
{ "name": "fmt", "localPath": "vnext/external/fmt" },
{ "name": "folly", "localPath": "vnext/external/folly" },
{ "name": "fast-float", "localPath": "vnext/external/fast-float" }
]
}
File: .cspell.json
// cSpell Settings
{
"version": "0.2",
// American English. The broader "en" accepts both British and American
// spellings; "en-US" flags British forms (synthesised, behaviour, etc.)
// so contributors and AI assistants don't drift away from US conventions.
"language": "en-US",
"dictionaryDefinitions": [
{
"name": "project-words",
"path": "./.spelling",
"addWords": true
}
],
"dictionaries": ["project-words"],
"files": ["/*.{cpp,h,idl,cs,js,jsx,ts,tsx}"],
"ignorePaths": [
"/flow-typed/npm",
"node_modules",
"packages/@office-iss/react-native-win32-tester",
"packages/@react-native/tester",
"packages/@react-native-windows/tester",
"packages/react-native-platform-override/src/e2etest/collateral",
"vnext/Folly/TEMP_UntilFollyUpdate",
"vnext/ReactCommon/TEMP_UntilReactCommonUpdate"
],
"useGitignore": true,
"ignoreRegExpList": [
"require\('.+'\)", // Node require
" from '.+';", // Node import from
"\$FlowFixMe\[[a-z\-]+\]", // Ignore flow tags
"[@#][a-z\-\.]+", // Ignore @name or #name tags
"0x[0-9a-f]+ /\* tag_\w{5} \*/"
]
}
File: .yarnrc.yml
enableScripts: false
yarnPath: .yarn/releases/yarn-4.13.0.cjs
nodeLinker: node-modules
logFilters:
- code: "YN0002"
level: "error"
Don't pin a version younger than the ms/react-native-public feed's 7-day upstream
quarantine (8 = 7 + 1d margin), so yarn.lock only holds versions the feed can serve.
Exempt our first-party scopes, plus the upstream react-native family that integrate-rn
pins to exact nightlies (the age gate rejects even exact versions).
npmMinimalAgeGate: "8d"
npmPreapprovedPackages:
- "react-native-windows"
- "@react-native-windows/*"
- "@rnw-scripts/*"
- "@office-iss/*"
- "react-native"
- "@react-native/*"
File: change/@office-iss-react-native-win32-497539f3-70de-4116-8f1c-df8cc4ea8b66.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260408-8bac1df5a",
"packageName": "@office-iss/react-native-win32",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@office-iss-react-native-win32-5b2bd2a8-dc7c-4aae-940d-dbd686d9b680.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260519-58cd1bf58",
"packageName": "@office-iss/react-native-win32",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@office-iss-react-native-win32-71a332f6-b971-4735-903a-134dec05b08b.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@office-iss/react-native-win32",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@office-iss-react-native-win32-7e79438f-99c7-4ea0-833c-9c9b4686795a.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260325-d1809f0aa",
"packageName": "@office-iss/react-native-win32",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@office-iss-react-native-win32-851c2fb9-e545-430b-bbf9-bcc1431006f0.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260310-621592d1f",
"packageName": "@office-iss/react-native-win32",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@office-iss-react-native-win32-9861ec0a-7c5a-488b-89f6-42e4c0fd6e3b.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260704-e04ff69ab (July 4th)",
"packageName": "@office-iss/react-native-win32",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@office-iss-react-native-win32-9cd66295-a74c-4f98-b629-1c2dbe6b776e.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260604-63683f091 (June 4th)",
"packageName": "@office-iss/react-native-win32",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@office-iss-react-native-win32-d3f0401f-2fee-4fff-9289-0ae565f5b706.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260430-118198599",
"packageName": "@office-iss/react-native-win32",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-8ae15fdc-32a3-4c63-a313-dbf5efb9c616.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/automation",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-01a1df77-a318-4c02-ab37-0abec763c018.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260704-e04ff69ab (July 4th)",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-23b56dc7-86c4-49f6-8d80-1625bae2e1fe.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260519-58cd1bf58",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-58609dc1-dbb5-4bbe-9521-41be4bf14e9c.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260310-621592d1f",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-5ba4c8d9-55f3-4f2d-8e47-919405a4fbc1.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-7ac062f8-4585-49f7-99be-a168fbafb118.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260604-63683f091 (June 4th)",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-8908bd9d-3754-4e14-9435-305e04238a84.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260325-d1809f0aa",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-8d023083-63dd-4669-ac48-5651e21b7320.json
{
"type": "prerelease",
"comment": "0.81 to main pipelines sync",
"packageName": "@react-native-windows/automation-channel",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-a76c6195-c6fa-4047-a275-414692facd98.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260408-8bac1df5a",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-channel-e1cf1e3e-ad61-4288-b286-77d12091fe99.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260430-118198599",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-commands-0fd6759b-ff86-4994-871c-2373ae3735e9.json
{
"type": "prerelease",
"comment": "Normalize cache-busting Image URIs by query string instead of host so snapshots work against the E2E image fixture server",
"packageName": "@react-native-windows/automation-commands",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-automation-commands-2bb43d3e-2b7b-4fbe-b827-b24978735a49.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/automation-commands",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-27e8183f-31ac-4937-b7b2-67b833be8dbf.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/cli",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-2ff6dbf2-cb41-451e-933d-8e0d81238e72.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260430-118198599",
"packageName": "@react-native-windows/cli",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-4e9b6a8a-37e8-4089-8b2a-4b5a3038b429.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260325-d1809f0aa",
"packageName": "@react-native-windows/cli",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-5f26c350-5ea4-40e4-b502-99c38d1c3ed1.json
{
"type": "prerelease",
"comment": "Defer PowerShell discovery until a command or health check needs it so CLI configuration can load without Windows build tools.",
"packageName": "@react-native-windows/cli",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-66f8bb72-2223-4893-8a6a-2ab820ac0e0f.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260310-621592d1f",
"packageName": "@react-native-windows/cli",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-6b8a50d0-9854-4368-9877-c30ed421cc4b.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260704-e04ff69ab (July 4th)",
"packageName": "@react-native-windows/cli",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-7a8a81c5-7428-42e2-803a-91b91974d8be.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260408-8bac1df5a",
"packageName": "@react-native-windows/cli",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-aa343563-7366-418a-b528-6a4fef2fbf96.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260519-58cd1bf58",
"packageName": "@react-native-windows/cli",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-cli-be5d6e73-9e1f-4e7f-a0ff-65ff0661a65c.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260604-63683f091 (June 4th)",
"packageName": "@react-native-windows/cli",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-codegen-f1425bfc-86a3-461e-a3d4-7501ea2c4817.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/codegen",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-find-dotnet-tools-00e90c43-d6b0-46b3-ad82-ba3c4d0302ce.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/find-dotnet-tools",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-find-repo-root-b250592d-0b10-40bd-b815-3f8419c7953b.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/find-repo-root",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-fs-b1a1b547-1505-4bc5-9f00-fcc17c99ebad.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/fs",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-package-utils-c5b05ec3-ae40-4f25-aa02-a4ca1f755746.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/package-utils",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-perf-testing-1d772d74-03d8-409c-9bb9-54ec4fe59ed8.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260408-8bac1df5a",
"packageName": "@react-native-windows/perf-testing",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-perf-testing-32154695-eb6d-44dc-a0c8-59cb9bc65645.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/perf-testing",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-perf-testing-33791a23-ae76-4ba0-bf50-49a940d870e8.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260310-621592d1f",
"packageName": "@react-native-windows/perf-testing",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-perf-testing-4782393b-f81f-40b0-8748-03399dc8310d.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260325-d1809f0aa",
"packageName": "@react-native-windows/perf-testing",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-perf-testing-6c516ace-cfde-4130-b13c-d0371c73eb3f.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260430-118198599",
"packageName": "@react-native-windows/perf-testing",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-perf-testing-d1533cf9-5a10-47c5-bd07-43eaece19192.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260519-58cd1bf58",
"packageName": "@react-native-windows/perf-testing",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-perf-testing-db3c2e20-9515-46c5-a116-2bbec05dba20.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260604-63683f091 (June 4th)",
"packageName": "@react-native-windows/perf-testing",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-perf-testing-f2a9f95e-f64e-49b7-abec-efea59245c15.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260704-e04ff69ab (July 4th)",
"packageName": "@react-native-windows/perf-testing",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/@react-native-windows-telemetry-9b2c859b-3ad5-47c1-a3ae-5355e4a0eb54.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "@react-native-windows/telemetry",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-platform-override-512664c0-ea84-4894-b24f-5574cc6210ab.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "react-native-platform-override",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-124a4b14-773e-4635-805c-4c2804daf32e.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260704-e04ff69ab (July 4th)",
"packageName": "react-native-windows",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-22b1e2a3-5ecc-4c5c-b127-e625595c8026.json
{
"type": "prerelease",
"comment": "Raise UI Automation selection events when accessibilityState.selected changes.",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-254122ae-7bce-4975-8525-f33d13e656d3.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260519-58cd1bf58",
"packageName": "react-native-windows",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-329bb585-6ee5-469b-bc48-e5dd0cbe8e02.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260430-118198599",
"packageName": "react-native-windows",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-425fdab2-f5eb-4834-8a89-ee086d4bbcc2.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260310-621592d1f",
"packageName": "react-native-windows",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-580ee5e2-c630-4ce8-a1a3-14ee5a18a571.json
{
"type": "prerelease",
"comment": "Fix Modal title bar contrast when the native window is inactive",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-616b8467-8959-43d7-8f2a-8cb3c5897fa8.json
{
"type": "prerelease",
"comment": "Fix touch timestamps so PanResponder handles every move",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-6312f66b-0df9-4df7-b9d1-897bb9053c9a.json
{
"type": "prerelease",
"comment": "Use the generator-supported bootstrap for nightly library scaffolding.",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-6c31220d-2aaf-4475-a63d-7d8c856d502d.json
{
"type": "prerelease",
"comment": "0.81 to main pipelines sync",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-77fda7b1-66d2-49d3-998b-cbe38717cf0e.json
{
"type": "prerelease",
"comment": "Fix single-line TextInput text drawn below center by measuring content with an unconstrained height",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-b70b76c2-bf4c-4b15-b462-c0a9f5ad4d13.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260408-8bac1df5a",
"packageName": "react-native-windows",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-bfa58cdb-5f79-4c9f-984b-3991143d645d.json
{
"type": "prerelease",
"comment": "Ensure that our CLI lib tests use Yarn v4",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-d6902056-acc8-445d-8876-27be2de017a0.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "react-native-windows",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-d98eb67f-df7e-4563-8268-552f65ae1012.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260325-d1809f0aa",
"packageName": "react-native-windows",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-e32a4ff6-6759-4792-a18b-498c36881708.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260604-63683f091 (June 4th)",
"packageName": "react-native-windows",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-eba3d592-2ea0-4067-8880-2beea6638837.json
{
"type": "prerelease",
"comment": "Fix use-after-free crash when an Image is destroyed while its download is still in flight",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-f4eab9a1-89da-4344-bb29-9257605a9422.json
{
"type": "prerelease",
"comment": "Clamp Tooltip Position To Monitor",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
File: change/react-native-windows-init-16ec0cf4-0323-4825-8b44-56d9ba8848e7.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260430-118198599",
"packageName": "react-native-windows-init",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-init-53ef3775-da45-4571-b19b-dc779c19e5cc.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260310-621592d1f",
"packageName": "react-native-windows-init",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-init-56d3c634-0855-48b8-85b8-a6ea301c2204.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260408-8bac1df5a",
"packageName": "react-native-windows-init",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-init-6990a92e-cfea-4509-8b20-8c98a4edc367.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260704-e04ff69ab (July 4th)",
"packageName": "react-native-windows-init",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-init-80556143-a2fc-4cf1-a3ce-96b04e24f5fb.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260604-63683f091 (June 4th)",
"packageName": "react-native-windows-init",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-init-9307f84e-6fff-4286-a974-e7f06c3171d2.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.86.0-nightly-20260325-d1809f0aa",
"packageName": "react-native-windows-init",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-init-b8d75819-6fef-4547-9130-57631ad4ccaa.json
{
"type": "prerelease",
"comment": "Integrate RN nightly 0.88.0-nightly-20260805-f2188610c (Aug 5th)",
"packageName": "react-native-windows-init",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: change/react-native-windows-init-c5ae7d1c-1132-4cee-80f2-79f6a9aa0b4d.json
{
"type": "prerelease",
"comment": "Integrate React Native 0.87.0-nightly-20260519-58cd1bf58",
"packageName": "react-native-windows-init",
"email": "email not defined",
"dependentChangeType": "patch"
}
File: docs/branch-lifecycle-policy.md
Branch Lifecycle Policy
This repository enforces a branch lifecycle policy to keep the branch list clean and manageable. Stale branches are identified automatically and removed after a period of inactivity.
How It Works
A scheduled GitHub Action (cleanup-stale-branches.yml) runs every Monday at 08:00 UTC and scans all remote branches for inactivity.
Staleness Thresholds
| Branch type | Stale after | Examples |
|---|---|---|
copilot/* |
90 days | copilot/fix-xyz, copilot/workspace |
| All other branches | 180 days | user/feature, abhi/experiment |
Scheduled runs are always dry run (report only). Deletions require a manual trigger.
Protected Branches
The following branch patterns are always excluded from cleanup, regardless of age:
main/masterdeveloprelease/*hotfix/*archive/**-stable(e.g.,0.72-stable,0.80-stable)preview-*(e.g.,preview-0.80-test)
Additional Safeguards
- Open PRs โ Branches with any open pull request (including drafts) are automatically skipped.
How to Keep a Branch
If your branch must be retained beyond the staleness threshold, use any of these methods:
1. Use a protected prefix
Rename your branch under archive/:
git branch -m my-old-branch archive/my-old-branch
git push origin archive/my-old-branch
git push origin --delete my-old-branch2. Keep an open PR
Create or keep a pull request (even a draft) from your branch. The workflow skips any branch with an open PR.
3. Add the pattern to the workflow
Add your branch prefix to the PROTECTED regex in the workflow file and submit a PR.
Manual Cleanup
Maintainers can trigger the workflow manually from the Actions tab:
- Go to Actions โ Cleanup Stale Branches
- Click Run workflow
- Set
dry_run = falseto actually delete stale branches
FAQ
Q: What happens if my branch is deleted by mistake?
A: Git branch deletions on GitHub are reversible for a short period. You can also restore from a local clone.
Q: Will this delete branches with open pull requests?
A: No. The workflow checks for open PRs (including drafts) and skips those branches.
Q: What about stable and preview branches?
A: All *-stable and preview-* branches are protected by default and will never be deleted.
File: docs/branch-setup.md
Git branch setup
This document describes how to set up your development environment and contribute changes to the microsoft/react-native-windows project. This document assumes basic working knowledge with Git and related tools. We are providing instructions specific to this project.
Creating your own fork
If you wish to contribute changes back to the microsoft/react-native-windows repository, start by creating your own fork of the repository. This is essential. This will keep the number of branches on the main repository to a small count. There are lots of developers in this project and creating lots of branches on the main repository does not scale. In your own fork, you can create as many branches as you like.
- Navigate to GitHub with a browser and log in to your GitHub account. For the sake of this document, let's assume your username is johndoe.
- Navigate to the microsoft/react-native-windows repository in the same browser session.
- Click on the Fork button at the top right corner of the page.
- Create the fork under your account. Your GitHub profile should now show react-native-windows as one of your repositories.
- Create a folder on your device and clone your fork of the Microsoft repository. e.g.
https://github.com/johndoe/react-native-windows.git. Notice how your GitHub username is in the repository location.
> git clone https://github.com/johndoe/react-native-windows.gitSetting up the upstream repository
Before starting to contribute changes, please setup your upstream repository to the primary microsoft/react-native-windows repository.
- When you run
git remote -v, you should see only your fork in the output list
> git remote -v
origin https://github.com/johndoe/react-native-windows.git (fetch)
origin https://github.com/johndoe/react-native-windows.git (push)- Map the primary react-native-windows repository as the upstream remote
> git remote add upstream https://github.com/microsoft/react-native-windows.git- Now running
git remote -vshould show the upstream repository also
> git remote -v
origin https://github.com/johndoe/react-native-windows.git (fetch)
origin https://github.com/johndoe/react-native-windows.git (push)
upstream https://github.com/microsoft/react-native-windows.git (fetch)
upstream https://github.com/microsoft/react-native-windows.git (push)- At this point you are ready to start branching and contributing back changes.
Making code changes and creating a pull request
Create a branch from your fork and start making the code changes. We recommend using SourceTree for working in your repo. Once you are happy with the changes, and want to merge them to the main microsoft/react-native-windows project, create a pull request from your branch directly to "microsoft/react-native-windows main".
Members on the microsoft/react-native-windows core team will help merge your changes.
Merging upstream main branch into your fork's main branch
From time to time, your fork will get out of sync with the upstream remote. Use the following commands to get the main branch of your fork up to date.
> git fetch upstream
> git checkout main
> git pull upstream main
> git pushMerging upstream main into your current branch
Use these commands instead if you would like to update your current branch in your fork from the upstream remote.
> git fetch upstream
> git pull upstream main
> git pushFile: docs/build-pipelines.md
Build Pipelines
React Native Windows uses three Azure DevOps pipelines built on the Office and general 1ES Pipeline Templates.
Pipeline Overview
| Pipeline | File | Template | Trigger |
|---|---|---|---|
| CI | .ado/ci-pipeline.yml |
Office Official | Push to main, *-stable |
| PR | .ado/pr-pipeline.yml |
1ES Unofficial | PRs to main, *-stable |
| Release | .ado/release-pipeline.yml |
Office Official | Triggered by successful CI run |
CI and PR share a single build-template.yml that contains all build, test, and packaging logic. The buildEnvironment parameter (Continuous or PullRequest) controls what runs:
- Both: build, test, lint, NuGet pack, CLI init verification
- CI only: ESRP code signing, release tagging
- PR only: beachball change file check
Stages
Setup โโโฌโโ Build โโโโ CLI
โ
โโโ TestsSetup
Detects whether this is a release build (commit message starts with RELEASE:) or a developer build. For developer builds, runs beachball to bump versions. Publishes version variables for all downstream stages.
Build
Runs in parallel for each platform/configuration in the build matrix:
- Desktop (x64/x86/ARM64EC, Debug/Release) โ builds, runs unit and integration tests, signs shipping binaries (CI)
- Universal (x64/x86/ARM64, Debug/Release) โ builds, runs unit tests, signs shipping binaries (CI)
- Linting โ JS/TS lint, format check, override validation
- NPM Pack โ creates npm tarballs
- NuGet Pack โ downloads all build artifacts, packs NuGet packages, ESRP signs them (CI)
Each build job uses *-single.yml step templates that build the full .sln, run tests, and stage shipping artifacts โ we test what we ship.
Tests
Runs in parallel with Build (both depend only on Setup):
- Node Tests โ Jest-based JavaScript tests
- Playground โ builds playground apps across configs
- E2E Tests โ Fabric end-to-end tests
CLI
Depends on Build (needs the NuGet packages). Runs react-native init + react-native-windows init against the just-built packages to verify the developer experience works.
Agent Pools
| Pool | Used By |
|---|---|
fabric-internal-pool-large |
CI: all jobs |
rnw-pool-4 |
PR: most jobs (default) |
rnw-pool-8 |
PR: native builds |
PR uses public pools (no -microsoft suffix). The PR entry point overrides the pool defaults.
SDL & Compliance
The Office Official template (CI) handles SDL automatically:
- CredScan โ credential scanning
- BinSkim โ binary security analysis (per-job targets via
templateContext.sdl) - Component Governance โ open-source license compliance
- CodeQL โ static analysis
- ESLint โ JS/TS analysis (with exclusions)
PREfast, SpotBugs, and Bandit are disabled (no actionable findings for this repo).
Release Flow
- Developer merges a PR to
main - CI pipeline runs: build, test, sign, pack
- On success, a separate prepare-release-bot pipeline creates/updates a release PR (e.g.,
prepare-release/main) - When the release PR is merged (commit message:
RELEASE: ...), CI runs again as a release build:- Skips beachball bump (versions already committed)
- Builds, tests, signs, packs
- Tags the source commit (
react-native-windows_v<version>)
- Release pipeline triggers on successful CI, publishing packages to npm and NuGet feeds
Key Files
| File | Purpose |
|---|---|
.ado/ci-pipeline.yml |
CI entry point |
.ado/pr-pipeline.yml |
PR entry point |
.ado/build-template.yml |
Shared build/test/pack logic |
.ado/release-pipeline.yml |
Release pipeline (publishes to feeds) |
.ado/jobs/desktop-single.yml |
Desktop build + test steps |
.ado/jobs/universal-single.yml |
Universal build + test steps |
.ado/jobs/cli-init-windows.yml |
CLI init verification |
.ado/jobs/e2e-test.yml |
E2E test job |
.ado/jobs/playground.yml |
Playground build job |
.ado/jobs/linting.yml |
Linting job |
.ado/jobs/node-tests.yml |
Node/Jest test job |
.ado/templates/prep-and-pack-nuget.yml |
NuGet packing steps |
.ado/templates/esrp-codesign-*.yml |
ESRP signing steps |
File: docs/building-rnw.md
Building React-Native-Windows
- Make sure you have installed dependencies. Just run
vnext\scripts\rnw-dependencies.ps1in an elevated PowerShell session. - Install Git if you don't have it installed in your development machine
Build Steps
Clone the repo
cmdgit clone https://github.com/microsoft/react-native-windows.git cd react-native-windowsInstall dependencies, and run JS build steps
cmdyarnNote that react-native-windows is a monorepo and relies on monorepo tools like yarn and lage. See this page for more details.
Running the Playground app
There are two ways to run the app. In a fully managed easy way, or by manually running all the required steps:
Automatic
The playground app can be run in a completely automatic way by doing:
cd packages\playground
yarn windows --sln windows\playground.slnManual
Run the bundle server:
cd packages\playground
yarn startBuild solution
Using MSBuild
cmdMSBuild.exe [/p:Platform=$(TargetPlatform)] [/p:Configuration=$(TargetConfiguration)]Using Visual Studio IDE
- Open
Playground.sln. - Set your
Platformtox86orx64andConfigurationtoDebug. - Select
Project / Build Solution (Ctrl+Shift+B)
- Open
Ensure debugger is running
Open Chrome and navigate to http://localhost:8081/debugger-ui/ in a new tab. Press F12 or Ctrl+Shift+I in Chrome to open its Developer Tools.
Run the app
In Visual Studio, set Playground as the StartUp Project.
Run project (
F5orDebug / Start Debugging).
You now see your new app and Chrome should have loaded http://localhost:8081/debugger-ui/ in a new tab. Press F12 or Ctrl+Shift+I in Chrome to open its Developer Tools.
Load a sample bundle
- Press the "Load" button on the left side of the Windows 10 application window that appears.
The selected React Native component (defaulted to Bootstrap) should get loaded in the bottom of the application window
Try out the various samples by selecting from the comboboxes at the top of the application window and pressing "Load".
File: docs/contributing.md
Contributing to microsoft/react-native-windows
If this is your first time, below are some more detailed steps for getting your branch set up and submitting a PR. You can either do this with the command prompt or with a combination of the command prompt and SourceTree.
Setting up your branch for changes
For each bug or task you complete, it is recommended that you start with a fresh branch. If you have any lingering changes in your current branch that you want to save, go ahead and commit them. If you are just beginning, then you are good to go. On github, navigate to your repository which should be forked from microsoft/react-native-windows. If you haven't already created a fork, follow the steps in Git branch Setup. Above the list of files is a dropdown that should say 'main'. Use the dropdown to create a new branch and name is according to what you will be working on. (I.e. DropdownHighlight, CleanUpExamples, etc). Now you have created a new branch.
SourceTree:
If you are using SourceTree you will want your branch to show up in SourceTree so you can commit changes to your branch. It takes time for it to show up automatically, so you can make it show by running git remote update origin โprune in your command prompt from the root. Once you see your new branch in SourceTree under Remotes on the left navigation pane, double click on your branch to check it out locally. A dialog will come up and the default settings should be fine, click Ok.
Git Command Line
If you are using the command line, you will want to make sure you have your branch locally. It takes time for it to show up automatically, so you can make it show by running git remote update origin โprune in your command prompt from the root. Run git branch -a to see if your new branch shows up. Now you will want to check out your branch locally. You can do this with git checkout -b branch-name. Confirm you are now working out of the branch with git branch.
Make the fix
Now that your branch is set up and ready for commits, go ahead and fix the bug you are working on or make some small change that you want to check in.
Verify your changes
Manually test your fix, and ensure that all tests are in a good state
Commit your changes
SourceTree:
In SourceTree, click on commit in the top left. This won't actually do anything to your files, it will just change to show the commit UI. In the bottom container, stage all of the files you want to submit by selecting them and clicking "Stage". Add a short message in the textbox at the bottom on what is included in your change. This will not show as your entire submission text, just for this commit.
Git Command Line
To stage files using the command line, you need to run git add MyFileOne.tsx for each file. You can also look up how to add all files with changes under a directory. Next you will want to commit changes with git commit โm "This change updates the padding in the dropdown"
You can commit multiple times until you are ready to make a pull request. You should keep the message short since it will not be used in the bug notes and is just for keeping track of the multiple commits in one pull request.
Run auto-format
Run yarn format in the repository's root directory if you're making C++ changes.
Run yarn lint:fix if making JS/TS changes.
Provide changelog information
Run yarn change --branch upstream/main in the root of the repo.
Creating a Pull Request
SourceTree:
In SourceTree click Push.
Git Command Line
Run git push.
This will push any staged files you have in your branch.
Now go back to your fork on github. You should see a yellow bar at the top with your change and a button that says "Compare & Pull Request". Click that button.
Click "Create Pull Request".
A bunch of tests will automatically kick off to verify your PR. The tests marked as required must pass before a PR can be merged. Currently the Azure Dev Ops tests will not kick off automatically. -- These have to be kicked off by a team member.
Someone will also have to review your change before the change is allowed to be merged in. They may ask questions for more information or ask you to change things. Be sure to respond to their comments and push additional changes to the branch if they ask you to modify things before they sign off.
Now you are done! Celebrate!
File: docs/e2e-testing.md
End-to-End Testing
e2e-test-app project structure
A test app, test library and test cases are in /packages/e2e-test-app-fabric/, and are organized as below.
testโ includes Jest tests using webdriveriowindowsโ the UWP native appjest.config.jsโ configuration for Jest and WebDriverIO
Running Tests
Install WinAppDriver v1.2.1
This will be automatically done for you if you use the RNW dependency script with rnwDev as an argument.
The E2E tests assume it is installed in the default location under C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe. If you choose a different path, you will need to specify it in /packages/e2e-test-app-fabric/jest.config.js.
module.exports = {
...
testEnvironmentOptions: {
...
winAppDriverBin: 'D:\\Program Files (x86)\\Windows Application Driver\\WinAppDriver.exe',
},
};Build the native test app
C:\repo\react-native-windows>
cd packages\e2e-test-app-fabricC:\repo\react-native-windows\packages\e2e-test-app-fabric>
yarn windows --no-launch
Running all tests
C:\repo\react-native-windows\packages\e2e-test-app-fabric>
yarn startC:\repo\react-native-windows\packages\e2e-test-app-fabric>
yarn e2etest
Running a specific test
C:\repo\react-native-windows\packages\e2e-test-app-fabric>
yarn start
โ Only the test filename (without the rest of the path) should be included.
C:\repo\react-native-windows\packages\e2e-test-app-fabric>
yarn e2etest visitAllPages.test.ts
Break on app start
C:\repo\react-native-windows\packages\e2e-test-app-fabric>
yarn startC:\repo\react-native-windows\packages\e2e-test-app-fabric>
yarn e2etest:debug visitAllPages.test.ts
Debugging E2E Tests in CI
Increasing verbosity
By default the only messages printed during tests are related to errors returned by WinAppDriver or assertion failures. It is possible to increase verbosity to show individual WebDriver wire commands by editing /packages/e2e-test-app-fabric/jest.config.js.
module.exports = {
...
testEnvironmentOptions: {
...
webdriverOptions: {
// Level of logging verbosity: trace | debug | info | warn | error
logLevel: 'error',
...
},
},
};Test Artifacts
If you have access to the AzureDevOps pipeline you'll be able to see test failures and debug crashes.
Here are the artifacts that are produced during the build:
- error screenshots of the app when a test failed
- test run XML - this contains some information like the name of the wdio test that failed and the JS stack
- tree dump outputs - you can compare these to the output of the main branch to see if there is a the difference responsible for the test failing.
- crash dumps of the e2e test app (RNTesterApp)
You can access these by going to the AzureDevOps run for your PR and clicking on the artifacts link:
Architecture
WinAppDriver
WinAppDriver uses UIA to
inspect and manipulate a test application, allowing clients to connect to it using the w3c WebDriver protocol.
WebDriverIO
WebDriverIO is a JavaScript library which connects to WinAppDriver using the WebDriver protocol. It provides global
APIs for querying the application UI tree such as selectors (see below) and a global browser object to manipulate the
test application.
Jest
Jest is the test runner used for end-to-end testing, including assertsion libraries, test selection, etc. WebDriverIO setup is
provided by a custom environment @react-native-windows/automation.
Authoring Tests
Tests are written using Jest and WebDriverIO (see more below) against a test app running RNTester. RNTester example
pages are used as Test UI, which is examined via Jest tests. Tests should attempt to target an existing RNTester page, but "Legacy" tests exist as custom pages only used by e2e-test-app-fabric
Writing a test against an RNTester example page
// LegacyControlStyleTestPage.test.ts
describe('FancyWidget', () => {
beforeAll(async () => {
await goToComponentExample('FancyWidget');
});
test('FancyWidget is populated with placeholder', async () => {
// Query for an element with accessibilityId of "foo" (see "locators" below)
const field = await app.findElementByTestID('foo');
expect(await field.getText()).toBe('placeholder');
});
});Adding a custom RNTester page
Before adding a custom page, consider whether the change can be made to an existing RNTester page and upstreamed. If needed, new examples may be integrated into the Windows fork of RNTester, @react-native-windows/tester.
Hooks are recommended to author the test page. (see https://reactjs.org/docs/hooks-intro.html and this Pluralsight course to learn more about Hooks)
// ControlStyleTestPage.tsx
export const title = 'LegacyControlStyleTest';
export const description = 'Legacy e2e test for Control Styles';
export const examples = [
{
render: function(): JSX.Element {
return <ControlStyleTestPage />;
},
},
];// RNTesterList.windows.js
...
{
key: 'LegacyControlStyleTest',
module: require('../examples-win/LegacyTests/ControlStyleTestPage'),
},
...Snapshot tests
E2ETests uses snapshot tests to detect unintended visual changes. Instead
of testing against the react tree, e2e-test-app-fabric compares the fully rendered composition tree. This allows testing the
correctness of ViewComponents.
import {dumpVisualTree} from '@react-native-windows/automation-commands';
test('Example test', async () => {
const dump = await dumpVisualTree('test-id-here');
expect(dump).toMatchSnapshot();
});Snapshots can be updated by either:
- Locally running
jest --updateSnapshot. - Copying from the "shapshots" artifact uploaded from a failing PR
File: docs/inspector.md
Hermes Inspector
React Native for Windows with Hermes engine now supports direct JavaScript runtime inspection using tools such as Chrome or Edge devtools, VSCode debugger, Flipper etc. by implementing an in-process Chrome Debug Protocol server.
Please note that it is fundamentally different from "Remote JS Debugging", which loads the JavaScript bundle into a remote Chrome browser session with duplex communication over IPC channels.
We share the implementation (code and design) with other platforms wherever possible. All the external endpoints, APIs and protocols should be identical to React Native environments on other platforms.
Hence, we expect most tooling available on other platforms to just work on Windows. But, as of now, we have tested only with Chrome and Edge devtools.
Steps to enable direct debugging
- Initialize React Native Host,
- Turn on
DeveloperSupport - Turn on
FastRefresh - Turn on
Direct Debugging
- Turn on
- Ensure Dev-Server is running
- Start the application
After the app has booted,
- Navigate to
edge://inspectin Edge browser orchrome://inspectin Chrome browser - Enable Discover network targets and configure the target discovery settings to include
localhost:8081(or wherever the metro server is running) - Within a few seconds "Hermes React Native" should appear on the page as a remote target
- Click on the inspect link to launch the devtools page
- Click
Ctrl+Pto open source files and set break points - Alternatively, you can insert
debuggerstatements in source code to break on specific locations
In order to break on locations during boot, you can either
debuggerstatements during boot sequence will pause the runtime waiting for debugger to connect- Set break point and refresh the bundle through the Dev Server. The runtime will wait for debugger to attach.
Steps to enable heap profiling
Follow steps 1-7 from above, and then
- Click on the "Memory" tab in the inspector
- Heap snapshots and instrumented allocations with callstacks should be working.
Enable debugging/profiling on release builds
We keep the inspector turned off on release builds by default. If you want to debug or profile release builds, set the MSBuild property EnableHermesInspectorInReleaseFlavor to 'true' when building the platform.
File: docs/modern-inspector-details.md
Modern Inspector Support in React Native for Windows
Overview
The modern inspector is the Chrome DevToolsโbased debugging experience that ships with the latest
versions of React Native. This experience now works end-to-end for React Native for Windows (RNW)
applications, enabling parity with Android and iOS. The integration provides a unified way to inspect
JavaScript execution, evaluate console expressions, profile CPU and memory usage, and visualize the
component hierarchy for both the Paper and Composition UI stacks.
Modern Inspector Building Blocks
- Host Target โ One per
ReactHost; surfaces metadata, reload requests, pause overlays, and
implements the CDP-facing delegate (ReactInspectorHostTargetDelegate). - Instance Target โ Created for each React instance; registers runtime targets, tracks instance
lifecycle, and unregisters cleanly on reload. - Runtime Target & Agent โ Runtime targets map to JavaScript VMs; agents are per-session objects
that translate Chrome DevTools Protocol (CDP) messages into engine calls. RNW mirrors upstream
lifetimes so reloads tear everything down deterministically. - Frontend Channel โ Delivers JSON CDP payloads between the RNW host and DevTools.
- Inspector Thread โ A single
ReactInspectorThreadensures CDP work is serialized away from
the UI and JS queues. (iOS and Andrtoid use UI thread.) - Debugger Notifications โ
DebuggerNotifications.hbroadcasts pause/resume events so view
hosts can react (e.g., showing overlays or resuming when the debugger continues).
Windows Integration Points
- ReactHost & ReactOptions โ
ReactHostcreates theHostTarget, exposes it throughReactOptions::InspectorHostTarget, and implements reload/pause hooks. This is the jump-off point
for all inspector traffic. The inspector supported only if theUseDirectDebuggeris true. - ReactInstanceWin / OInstance โ Register and unregister instance/runtime targets around runtime
creation, keeping the inspector aligned with bridgeless and legacy bridge lifecycles. - DevSupportManager & Packager โ
DevSupportManagernow spins upReactInspectorPackagerConnectionDelegate, allowing Metro to broker modern inspector connections
and reuse the existing websocket infrastructure. - Dev Console Shortcut โ Metroโs
Jshortcut launches the inspector for Windows apps, matching
upstream behavior.
UI Overlays
- Composition โ
DebuggerUIIslandrenders pause overlays, focus chrome, and selection adorners
whenever the runtime is paused. - Paper โ
ReactRootViewupdates provide the same pause/selection affordances.
Hermes Runtime Integration
HermesRuntimeTargetDelegateandHermesRuntimeAgentDelegatewrap the hermes-windows C debug API
so we can re-use upstream modern inspector code.RuntimeHolder/HermesRuntimeHoldersurface acreateRuntimeTargetDelegatehook that instantiates
delegates only when the inspector is enabled, and safely tears them down during reloads.
Packager & Console Integration
ReactInspectorPackagerConnectionDelegatemaps the Metro websocket APIs to the modern inspector
handshake.- Console output, CPU sampling, and memory profiling are forwarded through the Hermes inspector
plumbing automatically once a session is active.
Using the Modern Inspector with RNW
- Start your Metro bundler (
npx react-native startoryarn start). - Launch your RNW app (Paper or Composition).
- In the Metro console, press
Jto open the modern inspector URL in a browser. - Chrome DevTools will connect to the Hermes runtime. Pause execution, explore the component tree,
and capture profiles as needed. - When execution is paused, the corresponding overlay is rendered in the app window; resume to clear
the overlay.
Known Limitations & Follow-Up Work
- Network profiling โ The
NetworkIOAgentis not wired up yet for Windows. The integration point
is theReactInspectorHostTargetDelegateinvnext/Microsoft.ReactNative/ReactHost/ReactHost.cpp; overrideloadNetworkResourcethere to
forward requests through a Windows HTTP helper (similar toGetJavaScriptFromServerAsync) and
stream results back via the providedNetworkRequestListener. Until this happens, the Network tab
in DevTools stays empty.
File: docs/monorepo.md
Monorepo details for react-native-windows
react-native-windows is a monorepo with several packages and uses monorepo management tools to install, build, and publish. This page is all about what tools we use to manage this monorepo and some technical details, aimed at folks who are contributing to react-native-windows.
Installation of npm dependencies
react-native-windows uses yarn workspaces to install all react-native-windows npm dependencies. See "workspaces" prop inside package.json.
Lage Build
react-native-windows uses lage to build all the "non-native" parts of react-native-windows. See "scripts" prop inside package.json. Also see laga.config.js.
Beachball publishing
TODO - add details
File: docs/project-structure.md
MSBuild Project Structure
This is a description of each of the core projects, their purpose and output artifacts.
Sample applications are not covered.
Alphabetical Index
- Common\Common.vcxproj
- Desktop\React.Windows.Desktop.vcxproj
- Desktop.DLL\React.Windows.Desktop.DLL.vcxproj
- Desktop.IntegrationTests\React.Windows.Desktop.IntegrationTests.vcxproj
- Desktop.UnitTests\React.Windows.Desktop.UnitTests.vcxproj
- Folly\Folly.vcxproj
- FollyWin32\FollyWin32.vcxproj
- IntegrationTests\React.Windows.IntegrationTests.vcxproj
- Microsoft.ReactNative\Microsoft.ReactNative.vcxproj
- Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems
- Microsoft.ReactNative.Managed\Microsoft.ReactNative.Managed.csproj
- Microsoft.ReactNative.SharedManaged\Microsoft.ReactNative.SharedManaged.projitems
- ReactCommon\ReactCommon.vcxproj
- ReactCommon.UnitTests\ReactCommon.UnitTests.vcxproj
- Shared\Shared.vcxitems
Common Projects
Common
Static Library
Functionality shared between React and JSI projects.
Microsoft.ReactNative.Shared
Shared Items (no build artifact)
Holds sources common to both Windows variants, that require different build configuration
(i.e. compiler flags, language standard).
ReactCommon
Static Library
React Native core, cross-platform C++ types and interfaces.
Sources provided as part of the react-native Node dependency. Not part of this repository.
See https://github.com/facebook/react-native/tree/v0.62.0/ReactCommon.
Folly
Static Library
Folly variant type system for JavaScript/C++ interoperability.
Sources provided as part of the react-native Node dependency. Not part of this repository.
Microsoft.ReactNative.Cxx
Shared Items (no build artifact)
Contains helpers to simplify authoring C++/WinRT native modules on top of Microsoft.ReactNative.
Microsoft.ReactNative.Managed
Managed Library
Contains helpers to simplify authoring C# native modules on top of Microsoft.ReactNative.
Microsoft.ReactNative.SharedManaged
Deprecated: This is still here so that customers get a specific error message on how to upgrade their project.
React.Windows.IntegrationTests
Static Library
Common framework for running out of process and/or full React instance testing.
IntegrationTests (Node Project)
MSBuild Node project. For reading/editing purposes only (no build artifact)
Set of JavaScript component tests for RNTester.
Sources provided as part of the react-native Node dependency. Not part of this repository.
See https://github.com/facebook/react-native/tree/v0.62.0/IntegrationTests.
Windows Desktop Projects
React.Windows.Desktop
Static Library
Set of Native Modules, View Managers and Executors for Windows Desktop.
React.Windows.Desktop.DLL
Dynamic Library
Shared library that exports the intended public API surface for React.Windows.Desktop.
Main artifact to use in Windows Desktop applications.
React.Windows.Desktop.UnitTests
VSTest Dynamic Library
Set of isolated (mocked) tests for types defined in React.Windows.Desktop.
React.Windows.Desktop.IntegrationTests
VSTest Dynamic Library
Set of component tests that validate functionality against external runtime components
(i.e. networking servers, file system, React Native applications, external processes).
Validates React.Windows.Desktop.DLL.
ReactCommon.UnitTests
Google Test Application
Gathers tests within react-native\ReactCommon.
Its main purpose is to validate JSI with any given engine (V8, etc).
FollyWin32
Static Library
Superset of Folly APIs only available and required by React.Windows.Desktop.
Sources provided as part of the react-native Node dependency. Not part of this repository.
Windows Universal Projects
Microsoft.ReactNative
Windows Runtime Component
The primary Windows Universal entry point and public API surface for React Native Windows.
Main artifact to use in Windows Universal applications.
File: docs/react-native-windows-init.md
React Native Windows initialization
This document describes how the template initialization works for react-native-windows init.
Where is the code:
The main logic that determines the template values and which files to apply is function copyProjectTemplateAndReplace in packages/@react-native-windows/cli/src/generator-windows/index.ts.
The parameters for init is located in variable argv in packages/react-native-windows-init/src/Cli.ts
The template files can be found in vnext/template
Debugging:
To debug the template, see Contributing to the CLI on our wiki.
Templating tech (Mustache)
PR #5126 updated the template generation for react-native-windows from regex replace to use the mustache template library.
Benefits
This has the following benefits:
- We can use conditionals and
foreachin the template allowing for better expressivity - This expressivity shows that we don't have to construct XML fragments in JavaScript anymore to be inserted by
regex.replace - We don't need to have have a copy and edit for large differences like we had for experimental NuGet, it is now a single template for each language.
- We can now generate a cpp template that use both NuGet AND WinUI3.
Research before setteling on Mustache
There are several templating schemes we could have chosen. We had a quick discussion and chose mustache as it is a well-adopted, lightweight library dedicated for templating.
Alternatives considered:
- js template expression: This would have required all files to become js programs that needed to be imported and evaluated. Since a lot of files contain data format or code, we would have likely had quite a few ugly escaping cases.
- T4: This would have required visual studio to be installed on the users machine and therefore only work on Windows. There were also some perf concerns and we would have to write and ship a standalone executable for the MSBuild tasks so we can call it from JavaScript.
Quick mustache tutorial:
For proper docs see the manual of mustache
But in short:
You run mustache via const text = mustache.render(inputText, obj); where obj is a regular JavaScript object.
For example:
{
name: 'you',
condition1: true,
condition2: false,
myIds: [
{ id: 'abc' },
{ id: 'xyz' }
]
}We only use 4 mustache elements replacement patterns:
- The template
Hello {{ name }}!will result inHello you!. - The template
Hello {{#condition1}}you!{{/condition1}}will result inHello you! - The template
Hello {{^condition2}}you!{{/condition2}}will result inHello you! - The template:will result in:text
MyIds: {{#myIds}} Id: {{ id }} {{/myIds}}textMyIds Id: abc Id: xyz
Future
In the future we hope this to be integrated with the react-native CLI templating scheme. At the moment there is only a very basic replacement scheme for a set of well-defined variables, so at the moment it is not suitable. When we get to that point we'll see if we can leverage that or contribute some improvements in the templating for react-native-init.
File: docs/sdl-gs-crash-monitoring.md
SDL Policy: /GS Stack Buffer Overrun Crash Monitoring
Overview
This document describes the process for monitoring, analyzing, and fixing /GS (stack buffer overrun) crashes in React Native Windows, in accordance with Microsoft's Security Development Lifecycle (SDL) policy requirements.
What is a /GS Crash?
A /GS crash occurs when the /GS compiler flag detects stack buffer corruption. The /GS flag adds security checks (stack cookies) to detect buffer overruns. When a mismatch is detected, the application is terminated with exception code 0xc0000409 (STATUS_STACK_BUFFER_OVERRUN).
SDL Policy Requirements
Per Microsoft SDL policy:
- All high-confidence /GS crashes must be analyzed and fixed when appropriate
- A monitoring plan must be in place to analyze future /GS failures within 60 days of being reported to Watson
- Teams must investigate all crashes that are not false-positives (
GS_FALSE_POSITIVE_*) - Fix identified stack buffer overruns to prevent potential security vulnerabilities
/GS Crash Classifications
Watson automatically classifies /GS crashes using the !gs debugger extension:
- GS_POSITIVE: High-confidence stack buffer overrun. MUST be fixed immediately.
- GS_SUSPECT: Suspected stack buffer overrun. Should be investigated.
- GS_FALSE_POSITIVE: False positive due to process corruption. Can be safely ignored.
Monitoring Process
1. Finding /GS Crashes in Watson
- Go to Watson
- Select "Buffer Overruns" under "Enter ANY of the following to see matching BUCKET(s)"
- Enter the application name (szAppName) or DLL name (szModName)
- Click "Show Crash/Hang Buckets"
- Filter for crashes with exception code
0xc0000409
2. Analyzing /GS Crashes
Use the provided Analyze-Crash.ps1 script to analyze crash dumps:
# Analyze a specific dump file
.\vnext\Scripts\Analyze-Crash.ps1 -DumpFilePath "path\to\crash.dmp"
# Or configure automatic dump collection for an exe
.\vnext\Scripts\Analyze-Crash.ps1 -ExeName "YourApp"The script will:
- Detect if the crash is a /GS crash (0xc0000409)
- Run the
!gsdebugger extension for detailed analysis - Classify the crash (GS_POSITIVE, GS_SUSPECT, or GS_FALSE_POSITIVE)
- Provide actionable guidance based on the classification
3. Triage and Response Timeline
| Classification | Priority | Action Required | Timeline |
|---|---|---|---|
| GS_POSITIVE | Critical | Analyze, fix, and test | Within 60 days of Watson report |
| GS_SUSPECT | High | Investigate and determine if real | Within 90 days |
| GS_FALSE_POSITIVE | Low | No action required | N/A |
4. Fixing /GS Crashes
When a real stack buffer overrun is identified:
Review the crash analysis
- Check the
!gsoutput in the analysis log - Identify the function with the buffer overrun
- Locate the source of the overrun (strcpy, sprintf, etc.)
- Check the
Implement the fix
- Replace unsafe functions with safe alternatives:
strcpyโstrcpy_sstrcatโstrcat_ssprintfโsprintf_sorsnprintfgetsโfgetsorgets_s
- Add bounds checking to array operations
- Validate input sizes before copying
- Replace unsafe functions with safe alternatives:
Test the fix
- Reproduce the original crash scenario
- Verify the crash no longer occurs
- Run existing tests to ensure no regressions
Document the fix
- Include CVE information if applicable
- Document the root cause and fix in commit message
- Update security documentation if needed
Common Vulnerable Patterns
Watch out for these common patterns that can lead to stack buffer overruns:
// UNSAFE: No bounds checking
char buffer[100];
strcpy(buffer, userInput); // โ
// SAFE: Use safe alternative with size
char buffer[100];
strcpy_s(buffer, sizeof(buffer), userInput); // โ
// UNSAFE: sprintf without size limit
char buffer[50];
sprintf(buffer, "Value: %s", userInput); // โ
// SAFE: Use snprintf with size limit
char buffer[50];
snprintf(buffer, sizeof(buffer), "Value: %s", userInput); // โ
// UNSAFE: Array access without bounds check
void ProcessArray(int* data, int count) {
int localArray[10];
for (int i = 0; i < count; i++) { // โ count could be > 10
localArray[i] = data[i];
}
}
// SAFE: Add bounds checking
void ProcessArray(int* data, int count) {
int localArray[10];
int safeCount = std::min(count, 10);
for (int i = 0; i < safeCount; i++) { // โ
localArray[i] = data[i];
}
}Reporting Security Issues
If a /GS crash is determined to be a security vulnerability:
- Do NOT create a public GitHub issue
- Report to Microsoft Security Response Center (MSRC):
- Online: https://msrc.microsoft.com/create-report
- Email: [email protected]
- Include:
- Type of issue (stack buffer overrun)
- Full paths of affected source files
- Steps to reproduce
- Crash dump and analysis (if safe to share)
- Potential security impact
See .github/security.md for full security reporting guidelines.
Tools and Resources
- Analyze-Crash.ps1: Automated crash analysis script with /GS detection
- Watson: https://aka.ms/watson - Microsoft crash reporting system
- !gs debugger extension: Built into Windows debuggers, analyzes /GS crashes
- !analyze -v: Verbose crash analysis including !gs output
Regular Monitoring Schedule
To comply with SDL requirements:
- Weekly: Check Watson for new /GS crashes
- Monthly: Review and triage all open /GS issues
- Quarterly: Audit codebase for unsafe string/buffer operations
- Before Release: Ensure no open GS_POSITIVE crashes remain
Questions?
For questions about /GS crashes or SDL policy:
- Internal: Contact your team's security champion
- External: File an issue in the repository (for non-security questions)
- Security issues: Follow the reporting process in .github/security.md
File: docs/testing-nuget-packages.md
Testing NuGet package for new @react-native-community/cli init templates.
Today's default is to use the C++ and C# code from the react-native-windows npm package as source. We have been working on moving to a binary distribution model for this code via NuGet.
Today we support the following projects as a NuGet package:
- Microsoft.ReactNative
- Microsoft.ReactNative.Managed
Testing NuGet packages is frequently a painful process as msbuild and NuGet lack referential transparency. The steps in this document hope to alleviate some of the challenges.
Complicating factors
- NuGet packages can only be loaded from a feed
These scripts help maintain a test feed on your local disk
- Each change requires a version bump.
NuGet caches by directory and simply checks if a directory with that version exists, regardless of whether the package has changed. It has implicit assumptions all up its stack that versions are immutable. Therefore each time you create a new package, you are forced to bump the versionpackage, you are forced to bupm the version - UWP NuGet packages contain multiple slices specific for each platform.
These scripts allow you to filter to specific slices so you don't have to build all flavors
Steps
- Decide which slices you want. The default is a single slice
'Debug,X64'but more are supported. - Decide on the version scheme. Recommended is:
0.0.1-MyTest001and keeping bumping the last 3 digigs - Build the bits in your repo for slice you selected
- open terminal for your enlistment (in vs dev prompt if you haven't setup your box otherwise)
- yarn
- yarn build
- pushd vnext
- NuGet restore Microsoft.ReactNative.sln
- msbuild Microsoft.ReactNative.sln /bl /m /p:Configuration=Debug /p:Platform=x64
- Repeat the preivous msbuild step for any other slices you might want to include
- Publish the NuGet packages
- open terminal for your enlistment
vnext\Scripts\PublishNuGetPackagesLocally.cmd 0.0.1-MyTest001
See below for a breakdown of the arguments
- Link your repo for fast CLI testing
- open terminal for your enlsitment
- push vnext
- yarn link
if it fails with already being registered for another enlistment you can run
yarn unlink
- Generate a test project
- open terminal in a test folder
npx @react-native-community/cli init MyProj- cd
MyProj - Apply the react-native-windows template:
node z:\src\r3\packages\react-native-windows-init\bin.js --useDevMode --overwrite --language cs --experimentalNuGetDependency --nuGetTestFeed c:\temp\RnWNuGetTesting\feed --nuGetTestVersion 0.0.1-MyTest001See below for a breakdown of the arguments:
- Deal with npm / nuget version mismatch
The nuget package checks to see if there is a version match between the nuget package and the npm package.
In testing these likely don't line up. You'll get the following error:texterror : Mismatch detected between npm package versions and nuget package version. error : Npm: '0.0.0-canary.148' - Z:\Temp\tst2\node_modules\react-native-windows\package.json error : NuGet: '0.0.1-MyTest010' - Z:\Temp\tst2\windows\tst2\tsts2.csproj error : To update the nuget version, please see https://microsoft.github.io/react-native-windows/docs/nuget-update for instructionsYou can disable the check by setting the environment variable:
set ReactNativeWindowsAllowNugetNpmMismatch=true
- Do your testing
Changes:
- Changes to the binaries in the NuGet package
- Rerun the builds for the slices you use
- Rerun publish NuGet script bumping the version number by one
- Reapply the windows template with the new version number
- Do your tests
- Change to the template generation
- yarn build
- Reapply the windows template
- Do your tests
Scripts
PublishNugetPackagesLocally
This script takes more options for more customization: <version> [<targetDir>] [<slices>] [] [].
Let's break down all arguments:
targetDir: Where the packages and feed should be placed. Default isc:\temp\RnWNugetTestingslices: This is the set of slices to produce in powershell array syntax. The default is:@('x64.Debug'). An example of more slices would be:@('x64.Debug', 'X86.Release', 'ARM64.Release')baseConfiguration: The slice that is used for the non configuration specific build outputs. Default is:DebugbasePlatform: The slice that is used for the non platform specific build outputs. Default isx64
react-native-windows-init ... cli.js
This script has many options, but let's break down the ones from the sample:
--version 0.0.0 --useDevMode: The version doesn't matter when using dev mode, which means that the npm package is used that is registred as the dev package usingyarn linkper instructions above. This saves copying all the output files to your package directory, to your yarn cache. It is also a lot faster and since it is a link, you can make changes to your enlistment i.e. tovnext\StyleSheetsand you don't have to reinstall between testing--overwrite: This just overwites files that already exist instead of prompting. This is very usefull when running the script multiple times to test the templates or to code that emits the template.--language cs: this is one of the public flags to generate a cs project instead of a cpp project.--experimentalNuGetDependency: This is the critical one to let the template emit referneces to NuGet package rather than source packages. When we make it the default this will likely be renamed back to source for those that need a tight loop between test projects from template and the product code for developers working 'on' react-native-windows. If it proves that the sample and test apps we have in the repo satisfy this need, it can be removed and the tempaltes can be cleaned up by removing a lot of the conditionals bewteen the two.--nuGetTestFeed c:\temp\RnWNugetTesting\feed: This flag adds an extra feed to the nuget.config so that for local testing you can use a different feed. This is the default location that is pushed to by thePublishNugetPackagesLocally.cmdscript.--nuGetTestVersion 0.0.1-MyTest001: By default the NuGet version matches the react-native version. For testing this can be cumbersome. Therefore this flag allows you to specify the version number for the NuGet packages.
File: docs/testing.md
Testing ReactNative for Windows
When contributing to this project, unit and integration tests should be run to help prevent new bugs and regressions.
Windows Desktop
Tests should be run with a VSTest-compatible client
(i.e. VSTest.Console.exe,
Visual Studio Test task).
This project includes convenience scripts to set up and run the test artifacts.
Unit Tests
Implemented in the React.Windows.Desktop.UnitTests project.
Isolated, self-contained tests covering concrete implementations against mock dependencies and data.
& Scripts\UnitTests.ps1Integration Tests
Implemented in the React.Windows.Desktop.IntegrationTests project.
Higher-level workflows interacting with real external dependencies (i.e. file system, networking servers).
These tests can run on the local development host.
# Starts test services and runs tests.
& Scripts\IntegrationTests.ps1E2E Tests
Implemented in packages/e2e-test-app
Please follow Author and Run E2E Test for React Native Windows for E2E Tests
File: docs/tracing.md
Event Tracing in ReactNative for Windows
React native for Windows implements an event provider using Event Tracing for Windows (ETW) framework, to enable instrumenting and analyzing performance critical source code. Events generated by an ETW provider can be observed and analyzed using tools available through Windows Performance Toolkit (WPT).
Currently, we have implemented the Systrace APIs on Windows to generate ETW events. Systrace APIs are used to instrument the core React Native source code. In future, we will instrument more of the React Native Windows source code with ETW events.
Tracing sessions can be managed as described below,
Start a tracing session
- Trace only events generated by React Native For Windows providers,
& .\vnext\Scripts\Tracing\Start-Tracing.ps1- Trace events generated by React Native For Windows as well as the general system providers,
& .\vnext\Scripts\Tracing\Start-Tracing.ps1 -IncludeGeneralTrace=$TrueStop a tracing session and anayze the traces
- Stop the session and start anaylizing the traces,
& .\vnext\Scripts\Tracing\Stop-Tracing.ps1- Stop the session only,
& .\vnext\Scripts\Tracing\Stop-Tracing.ps1 -NoAnalysis=$TrueFile: packages/README.md
This directory contains the npm packages hosted by the react-native-windows repo.
Scoped Packages
Several packages are organized into specific package scopes:
@office-iss: Office internal packages@react-native: Copies of private upstream packages already using the@react-nativescope. E.g.@react-native/testerfor the RNTester package.@react-native-windows: Internal packages used by react-native-windows itself. Versioned and published alongside RNW.@rnw-scripts: Scripts for repository tooling. Published as part of the main branch.
Unscoped packages
Several packages do not belong to a scope for intentional (or historical) reasons. E.g. react-native-platform-override isn't RNW-specific and
is unscoped. react-native-windows-init is run by name, and as such makes sense to be unscoped.
Adding a new scope
โ Caution: Failing to create and give access to an NPM organization will break CI.
New package scopes for related packages can be added by adding a new directory with the scope name and prefixing the
packages name in package.json with the scope.
E.g. for packages/@example-scope/create-widgets/package.json:
{
"name": "@example-scope/create-widgets",
...
}After adding a scope directory, add the scope to the list of yarn workspaces in the repo-root package.json.
"workspaces": {
"packages": [
...
"packages/@example-scope/*",
...
]
},Publishing a scoped package requires that the rnbot NPM user is an owner of an npm organization with the
same name as the scope. You can check whether an organization exists by viewing npmjs.com/org/
See acoates for granting permissions to rnbot.
File: packages/@office-iss/react-native-win32/README.md
@office-iss/react-native-win32
Internal use only
To better support some of our open source efforts, we are publishing this @office-iss/react-native-win32 JS package that office uses on win32. This is not a package that is generally consumable by other since it requires Office's UI framework which isn't open source. But it does allow some of our other cross platform efforts to be able to open source their work where previously its been unable to if Office win32 was one of the target platforms. This will enable projects such as our cross platform component libraries to be able to be published to open source.
Running react-native on win32.
We do have a solution for running react-native in a win32 app. You can run react-native-windows on win32 using Xaml Islands. We are working on expanding the set of supported Windows versions to broaden the support of that, and provide more samples of how to do that.