├── .github ├── ISSUE_TEMPLATE │ └── default.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── README.md ├── assets ├── element-inspector-legacy-panels.png ├── native-state-updates.png ├── npmsizegraph.png └── sync-events.png ├── core-meetings ├── 2018-07-ci-meeting.md ├── 2018-08-cli-meeting.md ├── 2018-09-metro-meeting.md ├── 2018-11-oss-meeting.md ├── 2019-11-21-rn-msft-collab-kickoff.md ├── 2019-12-05-rn-msft-weekly-sync.md ├── 2020-01-16-rn-msft-weekly-sync.md ├── 2020-02-26-issue-management-meeting.md ├── 2020-03-11-issue-management-meeting.md ├── 2020-03-25-issue-management-meeting.md ├── 2020-04-15-issue-management-meeting.md └── README.md ├── partners ├── 0000-partner-organizations.md ├── 0001-organization-repository-policy.md ├── 0002-apply-organization-repository-policy.md └── README.md └── proposals ├── 0000-template.md ├── 0003-webview.md ├── 0011-Turbo-Modules.md ├── 0013-Extracted-Command-Line-Tools.md ├── 0018-cocoapods-support-improvements.md ├── 0036-Official-Docker.md ├── 0054-a11y-roles-states-improvements.md ├── 0055-a11y-actions.md ├── 0480-react-native-monorepo.md ├── 0503-rn-versions-lifecycle-support.md ├── 0508-out-of-npm-artifacts.md ├── 0534-metro-package-exports-support.md ├── 0605-lazy-bundling.md ├── 0607-dom-traversal-and-layout-apis.md ├── 0641-decoupling-flipper-from-react-native-core.md ├── 0684-adding-e2e-in-core.md ├── 0744-well-defined-event-loop.md ├── 0759-react-native-frameworks.md ├── 0777-remove-legacy-element-inspector-features.md ├── 0836-lean-core-jsc.md ├── 0894-deprecate-subpath-imports.md ├── README.md └── assets ├── 0006-current-status.png ├── 0006-proposal.png ├── 0641-one-click-hermes-debug.png ├── 0744-fabric-current-async-update-embedded-diagram.png ├── 0744-fabric-event-loop-async-update-embedded-diagram.png └── 0744-fabric-event-loop-sync-update-embedded-diagram.png /.github/ISSUE_TEMPLATE/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Write a proposal ✍️' 3 | about: Start a new conversation about a broad topic for React Native 4 | --- 5 | 6 | 14 | 15 | ### Introduction 16 | 17 | 20 | 21 | ### Details 22 | 23 | 26 | 27 | ### Discussion points 28 | 29 | 32 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native: Discussions and Proposals 2 | 3 | Do you have an idea on how to make React Native better? 4 | 5 | Do you want to discuss an aspect of the framework? 6 | 7 | This repository is the right place to do so! 8 | 9 | ## Participate 10 | 11 | This repository was born by the desire of more transparency from the Core and Facebook teams, and a dedicated communication channels for all the members of the community. 12 | 13 | In order to do so, it has been decided to focus this repository to provide a safe environment to generate interesting conversations related to the [main React Native](https://github.com/facebook/react-native) repository. 14 | 15 | ### Discussions 16 | 17 | React Native is still a young framework, and its rapid release cycle leaves the door open for discussing how it can evolve at every step of the way. 18 | 19 | The issue section of this repository is open for anyone to propose a subject related to the React Native library that deserves a discussion. 20 | 21 | ### Proposals 22 | 23 | The "RFC" (request for comments) process is intended to provide a consistent and controlled path for new features to be proposed and championed to then enter the project. 24 | 25 | It is inspired by the [React RFC repo](https://github.com/reactjs/rfcs), but today we don't expect for every substantial change to go through this process; however, we hope that this brings more awareness to the community. 26 | 27 | ### Core Meetings 28 | 29 | The top contributors regularly meet to discuss ongoing problems with the goal of drafting solution proposals. The [core meetings](core-meetings/README.md) directory contains meeting notes and topics for this process. 30 | 31 | ## CoC 32 | 33 | Similarly to the main repository, this project has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated. 34 | -------------------------------------------------------------------------------- /assets/element-inspector-legacy-panels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/assets/element-inspector-legacy-panels.png -------------------------------------------------------------------------------- /assets/native-state-updates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/assets/native-state-updates.png -------------------------------------------------------------------------------- /assets/npmsizegraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/assets/npmsizegraph.png -------------------------------------------------------------------------------- /assets/sync-events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/assets/sync-events.png -------------------------------------------------------------------------------- /core-meetings/2018-07-ci-meeting.md: -------------------------------------------------------------------------------- 1 | # Better CI, Testing, and Proposals: July 2018 Core Meeting 2 | 3 | In case you missed [the release of 0.56](http://facebook.github.io/react-native/blog/2018/07/04/releasing-react-native-056), the teams behind React Native have been busy! Nevertheless, as stewards of React Native engineers worldwide, we've contemplated ways to improve alignment and visibility of the framework's direction, reason why we decided to bring back the monthly meetings (with an updated format), where community members and Facebook alike joined to discuss issues and propose responses. 4 | 5 | The community team is made up of volunteers who help maintain React Native, contribute to education materials, and improve the React Native developer's environment. 6 | 7 | ## The core discussion 8 | 9 | This time, the group chose to discuss React Native's continuous integration tooling. 10 | 11 | The React Native repository has a complex [continuous integration suite](https://circleci.com/gh/facebook/react-native) that automatically tests pull requests and master to help guarantee quality. These tests are actually split into five separate suites, ranging from checking for Flow errors to iOS end to end testing. CI should give confidence that things are good when merging pull requests and making release candidates. Recently though, CI success has been a challenge. It's even caused slowdowns in making releases. 12 | 13 | ## Make CI stay green 14 | 15 | In our discussion, the group identified two main problems with our use of CI today: automated test coverage is insufficient and Facebook inadvertently syncs problem changes. 16 | 17 | ### Better test coverage 18 | 19 | While the goal of CI is to help gain confidence in merging PRs, many areas of the codebase don't have enough test coverage to offer that. For instance in the first stable release of 0.56, there was an issue using the CLI on Windows. There are many areas of the codebase today that lack robust tests in the Github repository. 20 | 21 | One of the proposals is to offer faster landing of pull requests that include automated test coverage. 22 | 23 | ### Don't let master languish 24 | 25 | As mentioned in [How to Contribute](https://facebook.github.io/react-native/docs/contributing#our-development-process), the Github repository mirrors an internal repository used at Facebook. Master commits are synced between the two by an automated process, but there are some differences between the two codebases (e.g. Facebook doesn't use Cocoapods or the CLI internally). Another difference is in CI: the internal repository uses Phabricator and the open source repository uses CircleCI. Due to factors beyond the React Native team, the CIs used by the community team and the Facebook team may not get to be exactly similar. 26 | 27 | One of the proposals is to sync changes into a branch rather than directly into master. This is currently being drafted. 28 | 29 | Another proposal is to file tickets internally at Facebook when one of their changes breaks the community CI. Hector is currently working on a bot for this. 30 | 31 | Sometimes though, the trouble syncs are actually in React Native's dependencies like Yoga, Folly, and Metro. Facebook internally does not use version releases; they consider master to be the current version at all times. Sometimes changes to these break the CI, and that can be difficult to troubleshoot. A proposal was made to move all of these dependencies into the React Native repository, and a counter proposal was made to have the community maintain package releases of the dependencies. 32 | 33 | ## Increasing awareness 34 | 35 | Community engagement was a recurring topic on the call. Most of the discussion focused on automation, but what about increasing knowledge transfer? There's a proposal on teaching about the "under the hood" parts powering React Native, creating a separate recurring monthly tech talk. 36 | 37 | ### Proposals 38 | 39 | All of these proposals need a home, so we're creating a location and format for them. Our ambition is to bring these conversations into the public but not force a rigid process. We're working on this now. 40 | 41 | --- 42 | 43 | This time's topic was CI, but we are planning to cover much more. Expect to see many of these proposals soon in this repository, where we hope you will help us make React Native even better. 44 | -------------------------------------------------------------------------------- /core-meetings/2018-08-cli-meeting.md: -------------------------------------------------------------------------------- 1 | # The CLI and its future: August 2018 Core Meeting 2 | 3 | As stewards of React Native engineers worldwide, we've contemplated ways to improve alignment and visibility of the framework's direction, where community members and Facebook alike joined to discuss issues and propose responses. 4 | 5 | The community team is made up of volunteers who help maintain React Native, contribute to education materials, and improve the React Native developer's environment. 6 | 7 | ## The core discussion 8 | 9 | This time, the group chose to discuss React Native's CLI tooling and its future. 10 | 11 | This conversation is part of the greater effort to [slim down the core repository](https://github.com/react-native-community/discussions-and-proposals/issues/6), while ensuring the code health. In particular, the starting point of this meeting was the [proposal](https://github.com/react-native-community/discussions-and-proposals/pull/13) of moving the CLI out of the main repo by [@grabbou](https://github.com/grabbou). 12 | 13 | ## Better decoupling 14 | 15 | In our discussion, the group identified that by moving the CLI tooling outside of the main repo, the Metro dependency would be _potentially_ decoupled from the main react-native library - it seems that the only files outside `/local-cli` referring to Metro are: 16 | 17 | - [HMRClient](https://github.com/facebook/react-native/blob/master/Libraries/Utilities/HMRClient.js) 18 | - [jest/preprocessor](https://github.com/facebook/react-native/blob/master/jest/preprocessor.js) 19 | 20 | Which also means that potentially moving it outside could make React Native more "packager agnostic". 21 | 22 | That said, extracting it is not "mandatory" for having first class support of third-party libraries such as RN-Windows or RN-Dom. 23 | 24 | A potential issue that may raise from this complete decoupling would be related to making sure that the different repos are always up-to-date with the newer versions of Metro (which are released quite frequently). 25 | 26 | ## `upgrade` and `react-native-git-upgrade` 27 | 28 | The conversation then shifted towards a portion of the React Native DX which is related to updating existing React Native projects to newer versions; in the CLI there are two different commands to help with it, but newer releases are showing their limitations. 29 | 30 | We are all aware of the complexities that updating to a newer React Native version can cause, and given that `react-native-git-upgrade` is the "most user-friendly" approach - but at the same time the least maintained - we tried to get back to the reason why it was merged and how it works: we found the [original PR](https://github.com/facebook/react-native/pull/11052) and the [blog-post](https://facebook.github.io/react-native/blog/2016/12/05/easier-upgrades) to help us in this. 31 | 32 | Given that most of the group actually manually upgrades the files to ensure a smooth transition in their projects, we discussed a lot about what an alternative to `git-upgrade` would look like. Since we couldn't come up with a "one for all" solution (we even considered code-mods) we agreed on: 33 | 34 | 1. trying to get more members of the community involved with maintaining this portion of the CLI. 35 | 1. similarly to Expo's approach, to write clear "how to manually upgrade" steps in the Changelog for new versions 36 | 37 | --- 38 | 39 | This time's topic was CLI, but we are planning to cover much more. You can check both the issues and the PRs of this repository to see what conversations are ongoing, and we hope you will join us in making React Native even better! 40 | -------------------------------------------------------------------------------- /core-meetings/2018-09-metro-meeting.md: -------------------------------------------------------------------------------- 1 | # Metro configurations changes: September 2018 Core Meeting 2 | 3 | As stewards of React Native engineers worldwide, we've contemplated ways to improve alignment and visibility of the framework's direction, where community members and Facebook alike joined to discuss issues and propose responses. 4 | 5 | The community team is made up of volunteers who help maintain React Native, contribute to education materials, and improve the React Native developer's environment. 6 | 7 | ## The core discussion 8 | 9 | This time, the core team - thanks to the fact that some of us were at React Native EU 2018 - met briefly to discuss some features of the [Metro bundler](https://github.com/facebook/metro), used by default to generate the Javascript package that is consumed by RN-generated apps. 10 | 11 | Over a year ago the Metro team added additional features that cause a large improvement to startup performance for virtually all React Native apps. Namely, [Inline requires](https://facebook.github.io/react-native/docs/0.56/performance#unbundling-inline-requires) and [Ram bundling](https://facebook.github.io/metro/docs/en/bundling#indexed-ram-bundle). Unfortunately, mostly because of poor communication, the majority of the developers didn’t know about them. 12 | 13 | These features are powerful advancements towards a more performant bundling and startup time for all React Native apps, but at the same time are "breaking changes" in the way they generate the bundle. 14 | 15 | This means that just sliding these features in and turn them on by default is not a viable solution for many in the community, that would all of a sudden face a new change to handle. 16 | 17 | Moreover, a new "format" of the bundle would interfere with the standard behavior of most _Over The Air_ update systems like Expo's or Codepush - since they by default generate non-ram bundled files to serve to the RN apps. 18 | 19 | The last point discussed was about where the configuration for these feature should be possible to be written - newer versions of Metro can consume a `metro.config.js` file, but historically there is also a `rn-cli.config.js` to consider (that will not be deprecated for the forseeable future); another option was, similar to `jest`, to be able to have it inline in the `package.json`. 20 | 21 | The conversation led to the following multi step, multi release rollout in order to help people get these features without breaking their projects: 22 | 23 | ### Actions that will be taken 24 | 25 | 1. we will communicate about these changes to OTA services like Expo's and Codepush so that they will be able to create bundles accordingly to the new configuration 26 | 1. starting v0.58, all React Native projects will have these flags explicitly set to `false` by default (0.57 is not affected by this), since `react-native-git-upgrade` will make them appear in projects being updated. This will allow for easy optional "jump in" by developers. 27 | 1. in the Changelog for 0.58 we will write about these new flags 28 | 1. based on the future of the CLI, we'll try to have `metro` being configurable via `rn-cli.config.js` or similar files (and not only from `metro.config.js`) 29 | 30 | --- 31 | 32 | This time's topic was Metro configuration, but we are planning to cover much more. You can check both the issues and the PRs of this repository to see what conversations are ongoing, and we hope you will join us in making React Native even better! 33 | -------------------------------------------------------------------------------- /core-meetings/2018-11-oss-meeting.md: -------------------------------------------------------------------------------- 1 | # Open Source Maintenance: November 2018 Core Meeting 2 | 3 | As stewards of React Native engineers worldwide, we've contemplated ways to improve alignment and visibility of the framework's direction, where community members and Facebook alike joined to discuss issues and propose responses. 4 | 5 | The community team is made up of volunteers who help maintain React Native, contribute to education materials, and improve the React Native developer's environment. 6 | 7 | ## The core discussion 8 | 9 | This time, many members from both the community and the FB team met to talk about the Open Source repository and its maintenance. 10 | 11 | The first part of the conversation was about two aspects of the current release (0.57.x): 12 | 13 | - how the React sync commits land in master, and have impacted the releases 14 | - how to tackle the patch releases and cherry picks request, given that over time this is more complex and prone to merge conflicts (because of the speed at which master branch moves) 15 | 16 | During the discussion, the FB team also clarified a couple of points from their latest blogpost about [Open Source Roadmap](http://facebook.github.io/react-native/blog/2018/11/01/oss-roadmap), here reported for transparency sake: 17 | 18 | - the internal FB team is _not_ switching React Native's source of truth to be GitHub first: they are simply changing _how_ they consume the React Native APIs internally. Which means that, internally, instead of writing `const View = require('View')` they will be writing `const {View} = require('react-native')` 19 | 20 | The GitHub repository will continue serving as a mirror of the commits that land in the internal react-native-github directory in Facebook's monorepo, and pulling in changes from open source will still require importing a PR to the monorepo rather than merging directly to master on GitHub. 21 | 22 | - the FB team is not foreseeing taking management or ownership of the release cycle\*; this was motivated by a few reasons, such as: 23 | - Wanting to generate more community participation. 24 | - The community probably know more about this than FB: given that the releases is how the community consumes RN, they should have the power to decide the release cycle. 25 | 26 | The second and last part of the meeting was dedicated to the upcoming version 0.58 - it was clarified that the JSI that has landed on master should not directly affect developers consuming React Native, and an issue to facilitate the discussion about it will be open on this repo (but no blog post should be expected). 27 | 28 | During the meeting, the subject of having a single organization to host the React Native components & libraries maintained by the community was briefly touched (given that currently there are two main ones, React Community and React Native Community) - but there wasn't time left so this will be discussed in a future meeting. 29 | 30 | ### Actions that will be taken 31 | 32 | 1. In patch level releases, from now on, there won't be important dependencies upgrades (unless strictly necessary) 33 | 2. A few tools to automate (at least partially) the release cycle will be tested and added to the process to reduce the workload on the maintainers (you can contribute to this conversation [here](https://github.com/react-native-community/discussions-and-proposals/issues/53)) 34 | 3. The [Releases.md](https://github.com/facebook/react-native/blob/master/Releases.md) file will be updated to reflect the current set of steps necessary for a release 35 | 4. For cherry pick requests, in case of complexities emerging during the release process, the author of the request will be asked to create a PR towards the branch 36 | 5. The FB team will attempt to be more empathetic when landing commits like React syncs to prevent issues 37 | 6. Another maintenance meeting will happen before end of the year, and among other things we'll discuss about a shared guideline for how to maintain repos owned by the community in order to help each other 38 | 39 | --- 40 | 41 | This time's topic was Open Source Maintenance, but we are planning to cover much more. You can check both the issues and the PRs of this repository to see what conversations are ongoing, and we hope you will join us in making React Native even better! 42 | 43 | \* this conversation sparked more discussion on the larger topic of maintainability & sustainability of the RN project - that is still ongoing. You can see the key points and join the conversation in this [dedicated discussion](https://github.com/react-native-community/discussions-and-proposals/issues/58). 44 | -------------------------------------------------------------------------------- /core-meetings/2019-11-21-rn-msft-collab-kickoff.md: -------------------------------------------------------------------------------- 1 | # Deeper collaboration with Microsoft : November 21, 2019 meeting 2 | A few key stakeholders from Facebook's React Native team and Microsoft teams met for a summit at Redmond a couple of weeks ago and discussed several topics over the course of 2 days. Our takeaways from the summit will make its way into a blogpost shortly. A lot of concrete opportunities to work more closely together were identified across the summit and we’re starting with a weekly meeting series between key stakeholders to begin to plan and make progress on those. 3 | 4 | We kicked off the first of these meetings last week. Below are some of the high level topics discussed. We will ensure to post notes from our working meetings publicly in this repo as we work out how to broaden it and bring in more participants from the community as well. 5 | 6 | ## Proposal for dealing with platform specific features 7 | React Native lean core contains several features that work only on iOS/tvOS/Android etc., Similarly, as support for React Native for Windows and Mac have been bootstrapped, there are corresponding features that tend to be platfrom specific, but still meaningfully part of the lean core API set. We will be reviewing a set of options including coding practices, PR principles and documentation concerns for dealing with props that are inherently platform specific and cannot be implemented across all platforms as well as props that may originate in one (or) more platforms and upon broader vetting and validation becomes supported over time across platforms. 8 | 9 | ## CI infrastructure 10 | A v-team has been identified to put together recommendations for a common and consistent CI infrastructure across facebook/react-native repo, microsoft/react-native-windows repo as well as react-native-community repos. Once some recommendations have been identified, we will share them with the community and expect to begin rollout post January 2020. In addition, a few folks will also be working on bootstrapping a benchmarking suite running on CI for every supported platform to help identify and get ahead of performance regressions, memory leaks, App size concerns etc., Static analysis tools and recommendations in this area will be published as we bootstrap. 11 | Post these, we will be working on a broader test infrastructure and validation suite for react-native with consistent documentations and help for best practices and recommendations in this area. 12 | 13 | ## Flow-TypeScript bridging 14 | Collaborations have been kicked off to help create any Codegen based automated bridging solution for supporting TypeScript better as well as some processes to ensure quality of Typescript definitions as new APIs get added. 15 | 16 | ## Instance management 17 | The teams from Microsoft and Facebook shared each other's designs for better and high performance instance management in React Native. A lot of concrete ways to converge these designs for an overall better architecture were identified and we are excited to collaborate on improvements in this space. 18 | 19 | ## Community and ecosystem 20 | In order to support an ecosystem of scale across more platforms, a working group will be publishing some processes, principles and guidelines for creating and maintaining high quality community modules with support for latest versions and all platforms including Windows and Mac. 21 | 22 | There is a lot more to come. Stay tuned! 23 | 24 | -------------------------------------------------------------------------------- /core-meetings/2019-12-05-rn-msft-weekly-sync.md: -------------------------------------------------------------------------------- 1 | # React Native & Microsoft Weekly Sync : December 5, 2019 2 | 3 | We are slowly getting into a rhythm for the weekly syncs. Some of the key topics that came up this week include the following: 4 | 5 | ## New features, breaking changes 6 | [Pressable](https://github.com/facebook/react-native/commits?author=yungsters&since=2019-11-27&until=2019-12-05) is coming soon! No breaking changes of note at this time. 7 | 8 | ## High quality community modules 9 | As a corollary to the discussions around [what packages belong in react-native-community](https://github.com/react-native-community/discussions-and-proposals/issues/176), there is a need to surface principles, best practices and even tooling for how customers of react-native can navigate the ecosystem and identify high quality, trustworthy, well maintained, cross-platform modules for their app needs. We had a good conversation on this topic with representatives from [Expo](https://expo.io/), Facebook and Microsoft. A proposal is being drafted including inputs from the discussions thread and will be shared in this repo in the New Year to take the discussion forward with the community. 10 | 11 | ## API documentation 12 | A few folks from Microsoft and Facebook have been tagged to collaborate on figuring out code-generated API stubs for a more thorough API documentation for react-native core as well as platform specific APIs. We will share more of our plans and timelines in this area in the New Year. 13 | 14 | ## "Things you don't like about React Native" 15 | A post has been a bit overdue to collate and respond to the most recent thread on [Things you don't like about React Native](https://github.com/react-native-community/discussions-and-proposals/issues/134). We will be collaborating on publishing a response in the New Year. Stay tuned! 16 | -------------------------------------------------------------------------------- /core-meetings/2020-01-16-rn-msft-weekly-sync.md: -------------------------------------------------------------------------------- 1 | # React Native & Microsoft Weekly Sync : January 16, 2020 2 | 3 | After a short break during the holiday season, we are back to business in 2020. 4 | 5 | ## Open source collaboration 6 | 7 | In an attempt to run more of our collaboration in the open and have the rest of the community participate in more of the conversations, we are trying out a few tracks: 8 | 9 | ### 1. Discussions in the open: 10 | You might have noticed a flurry of activity in the Issues section of this repo in the last couple of weeks. At this time, almost all the internal discussion topics that we are collaborating on have been filed as [Issues](https://github.com/react-native-community/discussions-and-proposals/issues). This is being done to ensure a broader perspective on topics and to solicit feedback from the core contributors as well as wider community members as we work to evolve the React Native framework. Keeping discussions in the github repo allows for a consistent, persistent and singular source of truth across all collaborators. **Please participate in the issues and give us any feedback you see fit**. 11 | 12 | ### 2. Project management in the open: 13 | We have moved all internal workstreams and individual work items to this github. You can now track our progress the same way we will be managing our collaboration : through the [FB – MSFT Collaboration Project board](https://github.com/react-native-community/discussions-and-proposals/projects/1) 14 | 15 | ### 3. Triage and Issue management in the open: 16 | We will shortly be kicking off triage sessions with select stakeholders from each of our companies as well as core-contributors, other collaborators etc., for managing issues across several core React Native repos and expect to post processes/triage notes etc., as we go along. 17 | 18 | With these processes in place, these weekly notes will likely become a bit lighter as folks can follow along using the various sources above. We will capture any outliers as well as general topics in these notes going forward. 19 | -------------------------------------------------------------------------------- /core-meetings/2020-02-26-issue-management-meeting.md: -------------------------------------------------------------------------------- 1 | # React Native Issue Management Kickoff 2 | 3 | In this kickoff meeting, we briefly went through the issue triage process for React Native Windows. We also discussed what we'd like to get out of these meetings. The outcome of these discussions is covered in the following sections. 4 | 5 | ## Goals 6 | 7 | The primary goal of the triage meeting is to ensure issues are labeled properly and have clear reproduction steps, to request more information from issues that require it, and close issues. These actions should result in an actionable backlog of issues. 8 | 9 | As part of the process, issue managers may identify broad patterns and documentation opportunities. These can result in the creation of actionable issues in the core repo, website repo, or a community repo. They may also identify areas of opportunity for automation and improvement of the efficiency of the triage process, to be documented in the core repo wiki. 10 | 11 | Participants will engage meaningfully with React Native developers, communicating through issues with a broad timeline of what is being worked on, and when something is getting fixed. Participants will also ensure issues are being handled with the appropriate priority, identifying escalation paths as needed. 12 | 13 | ## Feedback 14 | 15 | - We will need to develop better templates/bots to maintain a high quality bar for issues, and ensure they are actionable right from the time of filing. 16 | - Handling issues that are not part of "core": We could add a bot that moves the issues to the respective repos including tagging the person who opened it and the owner of the repo and continue conversation there. It may be useful to keep 10 minutes per triage session for following up on most recent auto-moved issues to help out the community. 17 | - There may be some assignment of issues during triage - but this is more about making the issues actionable than creating specific accountability with product crew during the meeting. 18 | 19 | ## Process 20 | 21 | **Who's involved:** 22 | - Expo: @cruzach 23 | - Shopify: @pepibumur, @alexrs 24 | - Coinbase: @imownbey 25 | - SumoLogic: @safaiyeh 26 | - Callstack: @satya164 27 | - Microsoft: @chrisglein, @harinikmsft, @tido64, @sweggersen 28 | - Facebook: @hramos, @TheSavior 29 | 30 | **When/Where:** Wednesdays, 10 AM - 10:30 AM PDT/PST 31 | 32 | **What:** Starting with a mix of processes outlined in [React Native triage process](https://github.com/facebook/react-native/wiki/Issues#triaging-issues) and [React Native for Windows triage process](https://github.com/microsoft/react-native-windows/wiki/Triage-Process). 33 | -------------------------------------------------------------------------------- /core-meetings/2020-03-11-issue-management-meeting.md: -------------------------------------------------------------------------------- 1 | # 2020-03-11 React Native Issue Management Meeting 2 | 3 | We looked at the most recent issues that are tagged as "Needs: Triage": https://github.com/facebook/react-native/issues?q=is%3Aissue+is%3Aopen+label%3A%22Needs%3A+Triage+%3Amag%3A%22 4 | 5 | We had a chance to go through 8 issues and walk through the triage process. We discussed how the bot manages issues and what aspects of the process are not yet automated. We'll cover the outcome of each issue's triage process for today's meeting notes; in future meeting notes, we might only call out issues that required escalation or otherwise didn't meet our basic issue triage process. We are doing this with the goal of surfacing opportunities to improve how we handle issues in the React Native repository. 6 | 7 | ## Issues: 8 | 9 | - **Fetching api response too slow when debugging mode is off:** https://github.com/facebook/react-native/issues/28283 10 | - This being an issue that depends on a network call to an API, we decided to ask for a minimal reproduction in order to eliminate the possibility this is caused by something outside of React Native itself. 11 | - In cases like this, where the issue deals with slowness during the processing of a network call's response, we like to see a call being made to a known API endpoint (e.g. something anyone can reproduce themselves, without access to the original author's app server). We need the original author to spend more time digging into whether the slowness is present in the network call itself (e.g. for some reason, are they seeing that network calls within React Native take an order of magnitude longer to respond than when tested using a JS repl elsewhere? Or is the slowness happening as part of the json parsing of the response?) We need the original author to put in the work to ascertain this is an issue in React Native itself. 12 | - We asked for a Snack, even though the issue requires switching between development and release. The example code used to create a minimal repro for the Snack can be useful to whoever investigates the issue later. 13 | - **PropTypes to prop-types, Error evaluating React.PropTypes:** https://github.com/facebook/react-native/issues/28282 14 | - The environment info for this issue shows React Native 0.55 being used, but 0.61 is the latest stable as of this writing on March 11, 2020. We ask that everyone try the latest version before filing an issue, in order to eliminate the possibility that the issue may have been solved already. 15 | - Note that caution must be taken when looking at older issues. The author may have indeed verified the issue on what happened to be the latest release when they originally filed the issue. 16 | - The react-native-bot will only comment on an issue at creation time if the version listed does not match latest in the releases tab on GitHub. The bot will re-check if the issue is edited, but only to remove the label. It will not remove its own comment if it finds the issue is now using the latest version. 17 | - **Metro bundler does not start:** https://github.com/facebook/react-native/issues/28281 18 | - This was marked as a duplicate of a closed issue by someone in the thread. 19 | - We looked at the closed issue, and found it was closed after someone suggested they should post it to the CLI repo (https://github.com/react-native-community/cli/issues/484). 20 | - We let the author know that their issue was marked resolved there. If they need to, they can open a new issue in the cli repo. 21 | - **Android ignores unicode soft hyphen:** https://github.com/facebook/react-native/issues/28279 22 | - This issue makes good use of images to display the problem. 23 | - We labeled it as affecting the Text component, as well as being an issue that described a disparity in how different platforms behave. 24 | - **Crash in RCTWebSocketModule:** https://github.com/facebook/react-native/issues/28278 25 | - Crash reports are not a good fit for the repository. We ask the authors to investigate further and determine what the minimal repro is that causes the crash. Without this, it's unlikely anyone can help the author ascertain what causes the crash as we don't have access to the app's source code or the repro steps. 26 | - Even if we did have the source code and repro steps, it's out of scope of the repo to investigate crashes in individual apps without a minimal repro that can be reproduced in a Snack or a brand new "rn init" app. 27 | - **StatusBar and Flexibility:** https://github.com/facebook/react-native/issues/28276 28 | - Good use of \ and images to demonstrate the issue. Repro steps describe how one might get to a repro, but we do need actual code (ideally a Snack). With a repository of this size, the bar is set so that the person reporting an issue is responsible for doing the work to provide the repro. 29 | - **Duplicate protocol definition of RCTBridgeModule is ignored:** https://github.com/facebook/react-native/issues/28273 30 | - This issue mentions React Native 0.43.4 and Xcode 11.3. That version of React Native is very, very old as of this writing. Furthermore, Xcode 11.3 was released recently and it has only been tested with 0.61 and 0.62. Highly recommend they verify if this is still an issue on RN 0.61. 31 | - **CxxNativeModule:** https://github.com/facebook/react-native/issues/28271 32 | - This issue does not make full use of the issue template, but it does mention having being tested on 0.62, which is still in release candidate phase as of this writing. We do want to encourage more folks to test the release candidate versions, therefore we can give this issue a pass for not adhering to the template. 33 | - Flagged as affecting the RC, and asked if the author might be interested in sending a pull request with a fix. 34 | 35 | ## Areas of opportunity: 36 | 37 | The needs-response bot is now enabled in the repository. It will remove the "Needs: Author Feedback" label whenever the original author comments on an issue. It will not, however, add a label such as "Needs: Attention" after the author leaves a comment. Therefore, it's possible to lose track of issues where the author is waiting to hear back from us. We will leave these issues tagged as "Needs: Triage" for now. 38 | 39 | ## Action Items 40 | - [ ] @hramos: Investigate why the react-native-bot might fail to catch that an old version of RN is being used when the original author edits their issue and fills out the Environment info section. See Issue #28282. 41 | - [ ] upforgrabs: Automate adding the attention label when the original author responds to an issue previously labeled as "Needs: Author Feedback" 42 | 43 | ## Attendees: 44 | - Expo: @cruzach 45 | - SumoLogic: @safaiyeh 46 | - Microsoft: @chrisglein 47 | - Facebook: @TheSavior, @hramos 48 | -------------------------------------------------------------------------------- /core-meetings/2020-03-25-issue-management-meeting.md: -------------------------------------------------------------------------------- 1 | # 2020-03-25 React Native Issue Management Meeting 2 | 3 | ## Agenda: 4 | - Issue management meeting goals 5 | - Workflow enhancements 6 | - Go through Needs: Triage issues 7 | - Go through Needs: Attention issues 8 | - Discuss areas of improvement 9 | - Create action items 10 | 11 | ## Issue management meeting goals 12 | 13 | Héctor shared his thoughts on issue management: 14 | - Issue triage should be a low-friction and handled by a large group of community members 15 | - Issue management meeting is where we surface improvements to the issue triage process and handle escalation paths from community triage 16 | - Folks in the weekly meeting might not necessarily do the triage themselves, instead they 17 | - Shape how issues are managed 18 | - Define what a "good issue" is, the final state we want every issue to get to, where they are ready to be looked at by someone who is interested in providing a fix (which could be one of a RN FB team member, RN core team member, or a community member who has expressed interest) 19 | 20 | Getting there: 21 | - For the next week: 22 | - Meeting members to go through issues 3x/week and triage. Intent is to dogfood the process and surface workflow improvements. 23 | - Test out the new automations and surface any additional labels or canned responses that would be helpful. 24 | - Flag any issues that were tricky to triage. 25 | - Onboard community members into the issue triage group: 26 | - Let Eli or Héctor know, and we will grant them issue management permissions. This allows them to apply labels, close, reopen issues, on the core RN repository. 27 | - React Native Wiki contains issue triage workflow to onboard new folks: https://github.com/facebook/react-native/wiki/Issues#triaging-issues 28 | - After dogfooding workflow, 29 | - Create an escalation path for issue triage group: applying a "Needs: Issue Manager Attention" label. 30 | - Meeting to switch focus to issues tagged as such. 31 | 32 | ## Workflow enhancements 33 | 34 | The [label-actions](https://github.com/dessant/label-actions) GitHub App has been enabled for the core repository. It provides the following functionality: 35 | 36 | - Automatically adds a comment on issues whenever any of these labels is applied: 37 | - "Needs: Verify on Latest Version" 38 | - "Needs: Environment Info" 39 | - "Needs: Issue Template" 40 | - ...and also closes the issue when these labels are applied: 41 | - "Type: Invalid" 42 | - "Type: Question" 43 | - "Type: Docs" 44 | - "Resolution: For Stack Overflow" 45 | 46 | The full configuration file can be found in [`.github/label-actions.yml` 47 | ](https://github.com/facebook/react-native/blob/master/.github/label-actions.yml). Please feel free to send a pull request with enhancements to this config. 48 | 49 | The [needs-attention](https://github.com/hramos/needs-attention) GitHub Action has been enabled, and will trigger whenever a new comment is added to an issue. The goal is to manage the "Needs: Author Feedback" label and make sure we do not lose track of issues where we asked for more information. If an issue with this label gets a new comment from the original author of the issue, this action will replace the "Needs: Author Feedback" label with a "Needs: Attention" label. This is the same process used in the `react-native-windows` repository. 50 | 51 | The workflow is configured in [`.github/workflows/needs-attention.yml`](https://github.com/facebook/react-native/blob/master/.github/workflows/needs-attention.yml), and the action itself is hosted at https://github.com/hramos/needs-attention. Pull requests that enhance this workflow are welcome. 52 | 53 | ## Issue triage 54 | 55 | We went through a small number of issues with the goal of demonstrating the new label actions in use. We looked at [Issues that Need Triage](https://github.com/facebook/react-native/issues?q=is%3Aissue+is%3Aopen+label%3A%22Needs%3A+Triage+%3Amag%3A%22), as well as [Issues that Need Attention](https://github.com/facebook/react-native/issues?q=is%3Aissue+is%3Aopen+label%3A%22Needs%3A+Attention%22+). 56 | 57 | ## Action Items 58 | 59 | - See "Getting there" above. Everyone to go through issues ~3x/week before our next meeting, a single page of GitHub search results should be enough (25 issues). Remove the "Needs: Triage" label for each issue you've triaged, to avoid double dipping. 60 | - Identify folks in your community who would be interested in triaging issues. 61 | - Héctor to update Wiki with latest workflow decisions: https://github.com/facebook/react-native/wiki/Issues 62 | 63 | ## Attendees: 64 | - Coinbase: Ian Ownbey (@imownbey) 65 | - Expo: Charlie Cruzan (@cruzach) 66 | - SumoLogic: Jason Safaiyeh (@safaiyeh) 67 | - Facebook: Eli White (@TheSavior), Héctor Ramos (@hramos) 68 | -------------------------------------------------------------------------------- /core-meetings/2020-04-15-issue-management-meeting.md: -------------------------------------------------------------------------------- 1 | # 2020-04-15 React Native Issue Management Meeting 2 | 3 | ## Agenda: 4 | - Discuss common patterns observed in offline triage 5 | - Go through Needs: Issue Manager Attention issues 6 | - Go through Needs: Triage issues 7 | - Go through Needs: Attention issues 8 | - Discuss areas of improvement 9 | - Create action items 10 | 11 | ## Notes 12 | 13 | - No issues flagged [Needs: Issue Manager Attention](https://github.com/facebook/react-native/labels/Needs%3A%20Issue%20Manager%20Attention) this week 14 | - Lots of issue traffic from upgrade issues to 0.62 15 | - [Type: Upgrade Issue](https://github.com/facebook/react-native/labels/Type%3A%20Upgrade%20Issue) will redirect to the [Upgrade Support repository](https://github.com/react-native-community/upgrade-support) and close it. 16 | - Action item: Add some communication in the bot tag response that they should come back if they are unable to resolve their issue due to an actual bug. 17 | - Potentially retire these: [DX: Upgrading](https://github.com/facebook/react-native/labels/DX%3A%20Upgrading), [Issue When Upgrading](https://github.com/facebook/react-native/labels/Issue%20When%20Upgrading). 18 | - COVID cadence - offline every other week. 19 | - [Needs: Verify on Latest Version](https://github.com/facebook/react-native/labels/Needs%3A%20Verify%20on%20Latest%20Version) - what's the support window? Do we tag issues on 61 now that 62 is out? 20 | - If they filed against the latest version when they opened the issue, that's fine (at least for N-1). 21 | - Do we clear "Needs: Triage" if issue looks completely good? 22 | - Facebook team would still like to look through these for prioritization 23 | - Having a label that says "this issue is good" doesn't feel quite right 24 | - Suggestion: Add "positive tags" such as "has good repro", "good description", etc. 25 | - Of note, [Issue: Author Provided Repro](https://github.com/facebook/react-native/labels/Issue%3A%20Author%20Provided%20Repro) already exists, and we should use. 26 | - Noticed that the bot is automatically applying Component/API labels 27 | - Sounds like was preexisting functionality, there was a bug, and it was fixed. Yay! 28 | - Lot of Flipper issues? 29 | - Somewhat expected as it's new to 62. Now has [a label](https://github.com/facebook/react-native/labels/Flipper). 30 | - Meeting cadence in light of COVID-19 challenges and reduced meeting bandwidth 31 | - Chris is going to send out a fresh invite (moving from Harini), moving to biweekly 32 | - Can do an offline checkin in off weeks, as we're trying to beef up offline triage anyway 33 | - 0.62 issues and Expo 34 | - Expo won't be upgraded until ~June/July so snacks are not good for reproing 0.62 issues. 35 | - This is pretty much always a problem with updates to latest version (part of why snacks aren't a requirement) 36 | - Potential concern: Will Expo fall behind with the many-version updates expected on path to TurboModules? 37 | - Tip: issues with the documentation should be labeled [Type: Docs](https://github.com/facebook/react-native/labels/Type%3A%20Docs) (will close issue) 38 | - After meeting (and small offline follow ups) triage needed is at 127 39 | 40 | ## Attendees 41 | 42 | - Microsoft: Chris Glein (@chrisglein) 43 | - Coinbase: Ian Ownbey (@imownbey) 44 | - Expo: Charlie Cruzan (@cruzach) 45 | - SumoLogic: Jason Safaiyeh (@safaiyeh) 46 | - Facebook: Héctor Ramos (@hramos) 47 | -------------------------------------------------------------------------------- /core-meetings/README.md: -------------------------------------------------------------------------------- 1 | # Core Meetings 2 | 3 | The core team regularly meets to review technical and structural problems, creating proposals to address them. This directory contains information about these meetings, like the standing list of topics and notes from meetings. 4 | 5 | ## Meeting Topics 6 | 7 | The topics listed below have ongoing meetings. Expect to see more notes and proposals on these subjects. Please note that this is not be an exhaustive list; members are welcome to introduce topics where there is opportunity to collaborate, and being listed is not a barrier to progress. 8 | 9 | ### Issue Management 10 | 11 | The primary goal of the issue management meeting is to ensure processes are in place that lead to actionable issues - those that are labeled properly and include clear reproduction steps. 12 | 13 | ### Continuous Integration 14 | 15 | _Lead by [@grabbou](https://twitter.com/grabbou)_ 16 | 17 | Anything related to infrastructure and releasing React Native; state of PRs, current issues, and blockers from the CI point of view. 18 | 19 | ### ReasonML 20 | 21 | _Lead by [@grabbou](https://twitter.com/grabbou)_ 22 | 23 | ReasonML is growing in popularity and there's numerous attempts to bring first class React Native support. Discussion on the approaches underway and direction of the project. 24 | 25 | ### CLI 26 | 27 | _Lead by [@grabbou](https://twitter.com/grabbou)_ 28 | 29 | Everything related to the way we use command line to run React Native apps, linking, compiling, building and general developer experience. 30 | 31 | ## Meeting Notes 32 | 33 | - [2018-08 The CLI and its future](2018-08-cli-meeting.md) 34 | - [2018-07 Releases and Keeping CI green](2018-07-ci-meeting.md) 35 | - [2018-09 Metro](2018-09-metro-meeting.md) 36 | - [2018-11 OSS Chat](2018-11-oss-meeting.md) 37 | - [2019-11 React Native & Microsoft Collab](2019-11-21%20RN-MSFT-collab-kickoff.md) 38 | -------------------------------------------------------------------------------- /partners/0000-partner-organizations.md: -------------------------------------------------------------------------------- 1 | # Partner organizations and the React Native Community organization 2 | 3 | On April 17, 2019 an initial list of partner organizations was included in [a description of the React Native ecosystem](https://github.com/facebook/react-native/commit/a1250da64625c1da581fe600f805fd321cd12d4f) in the `facebook/react-native` repository. 4 | 5 | > Partners are companies that are significantly invested in React Native and have been for years. Informed by their use of React Native, they push for improvements of the core and/or the ecosystem around it. Facebook's partners think of React Native as a product: they understand the trade offs that the project makes as well as future plans and goals. Together we shape the vision for React Native to make it the best way to build applications. 6 | 7 | The list of partners can expand and contract over time. At the time of writing the current list of partners is, in alphabetic order: Callstack, Expo, Facebook, Infinite Red, Microsoft, and Software Mansion. Among these partners are creators and stakeholders in the React Native Community organization. 8 | 9 | ## React Native Community organization: formalizing a decision process 10 | 11 | The motivating example for the need for a more formalized decision process can be seen by looking at the ["What packages belong in react-native-community?"](https://github.com/react-native-community/discussions-and-proposals/issues/176) issue, which has remained open for nearly a year and a half despite being a fundamental question for the organization. Part of the reason that this question remained unanswered for so long is that there wasn't any formal decision making process in place for the organization and nobody wanted or had the authority to act unilaterally, so it wasn't clear how to proceed. 12 | 13 | The creators of the React Native Community organization decided that a practical way to make good decisions for the organization would be to have representatives from each of the React Native partner organizations vote on any proposals for significant changes. This would ensure that a diverse range of interests were considered while still limiting the number of parties involved to a small enough group to minimize overhead. 14 | 15 | To initialize a governance model, representatives from the partners took a vote that on the first proposal: "decisions that will meaningfully change the react-native-community organization will require approval by a majority of partners". To give all partners a voice in the initial decision, we agreed that this vote to establish majority rule would need to be passed unanimously. 16 | 17 | The vote passed 6-0, establishing a governance model where partners can make decisions on behalf of the react-native-community by majority rule. -------------------------------------------------------------------------------- /partners/0001-organization-repository-policy.md: -------------------------------------------------------------------------------- 1 | # What repositories belong in React Native Community? 2 | 3 | ## Summary of the current state 4 | 5 | #### The React Native Community organization has no official policy for what repositories belong or do not belong in the organization. It currently is home to four categories of repositories: 6 | 7 | 1) modules that were initially in the react-native repository but separated out (async-storage, etc). 8 | 2) packages used to support these modules (bob, etc). 9 | 3) resources for the react-native community (discussions-and-proposals, upgrade-helper, releases, etc). 10 | 4) arbitrary modules that were added at some point for different reasons (video, camera, linear-gradient, etc). 11 | 12 | > :bulb: [Check out this gist](https://gist.github.com/brentvatne/9ab778c9d68f48e47c9987690232d131) for a full list of repositories and their groupings 13 | 14 | #### React Native Community is perceived by developers in the ecosystem to be a 2nd party organization (not quite "core", blessed and worked on by Facebook and the core team, and not on the same level as other third parties) and packages are therefore assumed to be high quality, well supported, and generally trustworthy. 15 | 16 | Perceived affiliation between Facebook and the repositories in the organization is not desirable for Facebook or the community, but it's hard to avoid. The organization has some "official" repositories like `discussions-and-proposals` and `releases`, and so putting other libraries next to them naturally has this effect. The result is that the libraries in the organization have a marketing advantage over other libraries in the ecosystem, and this is counterproductive to creating an ecosystem where the best projects rise to the top. 17 | 18 | #### Developers use the React Native Community organization to discover packages ("does React Native Community have a package for X?") rather than a tool that is better suited for the job. 19 | 20 | Given the previous point, it makes sense that users will make the React Native Community organization their first stop in discovering libraries to use in their projects. GitHub organizations are not meant to serve as a directory for a community of projects and does a poor job of it compared to a purpose-built tool, such as React Native Directory, which is capable of listing projects from any organization and providing additional context to help developers make an informed decision. 21 | 22 | #### Authors and users of libraries frequently request that a library be moved to React Native Community. 23 | 24 | This could be because it is no longer maintained, or the author wants help, or users want more confidence that it will continue to be maintained, or the author wants to promote their library and get a boost to their library downloads and improve their CV or ability to sell their services to clients by association with the organization. 25 | 26 | The incentives for a developer to try to get a repository into the React Native Community organization hint at the underlying issues discussed above. 27 | 28 | There is no clear benefit to including tens or hundreds of libraries maintained by distinct groups of people (or not maintained) in a single organization, and so we have been holding off on adding new repositories to the organization until some clarity is achieved (hopefully through this discussion). 29 | 30 | ## Proposed change 31 | 32 | #### React Native Community will transition towards hosting only the repositories that fit into category 3. 33 | 34 | The organization will contain repositories that act as forums for structured discussions and/or provide information about React Native and the ecosystem. These repositories may be purely textual, or they may be tools like the Upgrade Helper and React Native Directory, depending on what is better suited for the job. The organization will not include libraries that developers install and use in their projects. 35 | 36 | Libraries that fit into categories 1, 2, and 4 will be moved to other organizations or users. For example, Callstack might take over some projects that they actively maintain and Microsoft might take others. Unaffiliated developers would just move the repository to their own personal GitHub or an organization built specifically for the repository, eg: http://github.com/react-navigation/. An action plan can be detailed at a later date. 37 | 38 | This also solves the issue of arbitrarily blessing specific solutions that may not be the best now or in the long term for the ecosystem. Rather than blessing specific libraries, we can direct developers to the [React Native Directory website](https://reactnative.directory) and continue iterating on it to help developers assess quality and discover and select the best packages for their needs. Additionally, we can move React Native Directory back to React Native Community. Developers who wanted to add their repository to the organization for marketing purposes can put it on the directory instead. 39 | 40 | ### Tradeoffs 41 | 42 | - Many packages have moved their name to the @react-native-community npm scope and removing that would create thrash. This is not a big deal for packages that are directly consumed by the developer, in my opinion, but it can be in places where the package is heavily depended on by other packages, eg: @react-native-community/async-storage is a building block for many other libraries. 43 | - Lean core libraries include some fundamental building blocks for most apps, like slider, net-info, progress-view, webview, and async-storage. Will moving them out of the organization make them more difficult to discover? 44 | 45 | ## Result 46 | 47 | Partners voted unanimously to approve the proposed change on 08/19/2020. -------------------------------------------------------------------------------- /partners/0002-apply-organization-repository-policy.md: -------------------------------------------------------------------------------- 1 | # Plan for applying the new React Native Community repository policy 2 | 3 | To summarize the descision made in ["What repositories belong in React Native Community?"](https://github.com/react-native-community/discussions-and-proposals/blob/master/partners/0000-organization-repository-policy.md): 4 | 5 | > The organization will contain repositories that act as forums for structured discussions and/or provide information about React Native and the ecosystem. These repositories may be purely textual, or they may be tools like the Upgrade Helper and React Native Directory, depending on what is better suited for the job. The only exception to this is React Native CLI, which will continue to live in React Native Community as long as the maintainers believe this to be the best home for it. 6 | 7 | [The partners making this decision](https://github.com/facebook/react-native/blob/master/ECOSYSTEM.md#partners) prioritize the health and growth of the community of React Native developers, which is much larger than those with maintainer access to any specific organization. High quality modules can and should come from anyone, anywhere. We recognize that developers value using the react-native-community brand as a library quality heuristic, but we believe that there are heuristics that are more useful and also healthier for the community. Our focus will be on things that scale; helping discoverability, making it easy to find quality packages, and building tooling to help create and maintain these packages. 8 | 9 | Now that a policy has been decided, we can move forward with enacting the changes to align the organization with it. As a maintainer of one of these packages, you don't need to wait to start making these changes. While you may follow what you think is best for your package, we are providing some recommended steps we think will help ease the migration. 10 | 11 | That said, **we know that changing package names can be challenging and a difficult transition for the ecosystem**. We will take care to support the community through this migration as best as we can. 12 | 13 | ## Where on GitHub will the repositories be moved to? 14 | 15 | Our recommendation for lean core libraries and libraries with multiple maintainers is to move them to their own dedicated organization, for example: react-native-webview would be moved to a new organization called react-native-webview, and would live at react-native-webview/webview. We have gone ahead and reserved all of the organizations by these names where possible, reach out to @brentvatne to have him transfer ownership to you if needed. 16 | 17 | If a library has just one maintainer, or is maintained only by developers from a single company, then the repository may be better suited for the individual or company GitHub account. 18 | 19 | Libraries that have been archived or otherwise abandoned will be moved to a React Native Community Archive organization in order to keep the repository list focused. 20 | 21 | If you a maintainer of a repository in the React Native Community organization and have any questions or concerns about how to proceed, or if you lack the required organization permissions, please let it be known in #community-hub. If you are not sure if you have the right/authority to act on moving a repository but consider yourself to be the primary maintainer, please also raise this in #community-hub. 22 | 23 | ## What should be done about packages that are scoped under @react-native-community on npm? 24 | 25 | We recommend deprecating the latest release with a message that the package name has changed, and republishing that exact same release under the new package name. Ideal package names may not always be available, but you might be able to reach out to the current owners of those packages and have them transfer ownership. 26 | 27 | Most packages that were not formerly available as part of React Native core are already unscoped. If your package used to exist without the @react-native-community scope and you have since migrated to it, you may consider migrating back to the original package name. 28 | 29 | ## How will developers discover commonly needed packages like async-storage, slider, webview, net-info, and others? 30 | 31 | [React Native Directory](https://reactnative.directory/) is the recommended resource for library discovery. We have surfaced it in the official documentation and may at some point merge the two. Further discussion on how we can surface some extremely commonly required dependencies should continue on [this issue](https://github.com/react-native-directory/website/issues/444). -------------------------------------------------------------------------------- /partners/README.md: -------------------------------------------------------------------------------- 1 | # Partners 2 | 3 | Members of the organizations [listed as partners on the react-native repository](https://github.com/facebook/react-native/blob/master/ECOSYSTEM.md#partners) collaborate to manage the React Native Community organization and related community tools, such as React Native Directory. Decisions that will meaningfully change the React Native Community organization require approval by a majority of partners. 4 | 5 | The scope of responsibility and list of partners is expected to change over time, and will be documented here alongside other decisions and actions. 6 | 7 | ## Documentation 8 | 9 | - [0000: Partner organizations and the React Native Community organization](0000-partner-organizations.md) 10 | - [0001: What repositories belong in React Native Community?](0001-organization-repository-policy.md) 11 | - [0002: Plan for applying the new React Native Community repository policy](0002-apply-organization-repository-policy.md) 12 | -------------------------------------------------------------------------------- /proposals/0000-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Title goes here 3 | author: 4 | - Jane Doe 5 | date: today 6 | --- 7 | 8 | # RFC0000: Title goes here 9 | 10 | ## Summary 11 | 12 | Brief explanation of the change. 13 | 14 | ## Basic example 15 | 16 | If the proposal involves a new or changed API, include a basic code example. Omit this section if it's not applicable. 17 | 18 | ## Motivation 19 | 20 | Why are we doing this? What use cases does it support? What is the expected outcome? 21 | 22 | Please focus on explaining the motivation so that if this RFC is not accepted, the motivation could be used to develop alternative solutions. In other words, enumerate the constraints you are trying to solve without coupling them too closely to the solution you have in mind. 23 | 24 | ## Detailed design 25 | 26 | This is the bulk of the RFC. Explain the design in enough detail for somebody familiar with React Native to understand, and for somebody familiar with the implementation to implement. This should get into specifics and corner-cases, and include examples of how the feature is used. Any new terminology should be defined here. 27 | 28 | ## Drawbacks 29 | 30 | Why should we _not_ do this? Please consider: 31 | 32 | - implementation cost, both in term of code size and complexity 33 | - whether the proposed feature can be implemented in user space 34 | - the impact on teaching people React Native 35 | - integration of this feature with other existing and planned features 36 | - cost of migrating existing React Native applications (is it a breaking change?) 37 | 38 | There are tradeoffs to choosing any path. Attempt to identify them here. 39 | 40 | ## Alternatives 41 | 42 | What other designs have been considered? Why did you select your approach? 43 | 44 | ## Adoption strategy 45 | 46 | If we implement this proposal, how will existing React Native developers adopt it? Is this a breaking change? Can we write a codemod? Should we coordinate with other projects or libraries? 47 | 48 | ## How we teach this 49 | 50 | What names and terminology work best for these concepts and why? How is this idea best presented? As a continuation of existing React patterns? 51 | 52 | Would the acceptance of this proposal mean the React Native documentation must be re-organized or altered? Does it change how React Native is taught to new developers at any level? 53 | 54 | How should this feature be taught to existing React Native developers? 55 | 56 | ## Unresolved questions 57 | 58 | Optional, but suggested for first drafts. What parts of the design are still TBD? 59 | -------------------------------------------------------------------------------- /proposals/0003-webview.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Extract WebView From Core 3 | author: 4 | - Jamon Holmgren 5 | date: 2018-07-30 6 | --- 7 | 8 | # RFC0003: Extract WebView From Core 9 | 10 | ## Summary 11 | 12 | Extract the current WebView implementation from React Native Core and move it into a third party package. 13 | 14 | ## Basic example 15 | 16 | Currently, WebView is included in React Native core: 17 | 18 | ```jsx 19 | import { WebView } from 'react-native'; 20 | ``` 21 | 22 | This would move it to an external package, like so: 23 | 24 | ```jsx 25 | import { WebView } from 'react-native-webview'; 26 | ``` 27 | 28 | (Where this third-party package will live is an open question. See below.) 29 | 30 | ## Motivation 31 | 32 | The current WebView implementation is used by Facebook internally but not actively updated. This leads (understandably) to a lack of first-class support for this core API. By moving the component to a third party that is more invested in supporting it, there will be better support. 33 | 34 | Additionally, with this component no longer included in core, there will be an opening for alternative third party WebView implementations, should anyone else wish to provide one. 35 | 36 | ## Detailed design 37 | 38 | For the first release, the goal is to provide the same API, only replacing the import statement and otherwise backwards compatible. 39 | 40 | We will also want to update generated project boilerplates, such as create-react-native-app and Ignite, to use the new package. 41 | 42 | ## Drawbacks 43 | 44 | This is a breaking change in that if someone simply updates their React Native version in an app that uses WebView and this core API is gone, their app will break. 45 | 46 | It also means there won't be an officially supported WebView in React Native, which may feel to some to be missing key functionality. 47 | 48 | ## Alternatives 49 | 50 | The primary alternative is to keep the WebView in core. There are also existing third party WebViews, although none that are reliably cross-platform. 51 | 52 | ## Adoption strategy 53 | 54 | This is a breaking change and existing React Native authors who use WebView will need to update their apps to access one of the third party solutions. For most, it should be as simple as `yarn add react-native-webview` and update their import statements. 55 | 56 | ## How we teach this 57 | 58 | We will need to update the React Native documentation to point out that WebView is now moved to a third party module. 59 | 60 | ## Unresolved questions 61 | 62 | There are a number of [WebView-related issues](https://github.com/facebook/react-native/search?q=webview&state=open&type=Issues) in the core React Native repo. We will need to have a plan to migrate those over to the new WebView repo. 63 | 64 | Additionally, we need to decide where this new repo will live. I am willing to host it under the `infinitered` organization (this motivates me more to keep it up to date and supported), but am open to other ideas such as `react-native-community`. 65 | -------------------------------------------------------------------------------- /proposals/0011-Turbo-Modules.md: -------------------------------------------------------------------------------- 1 | # RFC0011: Turbo Modules ™ 2 | _It's blazing fast_ 3 | 4 | ## Summary 5 | 6 | React Native uses [Native Modules](https://facebook.github.io/react-native/docs/native-modules-ios) as a way for JavaScript to invoke functions in Java/ObjC. Listed under the API section in the [React Native documentation](https://facebook.github.io/react-native/docs/getting-started), popular native modules include Geolocation, Device Information, Async Storage, etc. 7 | This proposal discusses a new architecture to speed up the way Native Modules are initialized and invoked from JavaScript. 8 | 9 | ## Motivation 10 | 11 | Here are some issues with the current state. Though Android is used as the example, the narrative applies to iOS also. 12 | 13 | 1. Native Modules are specified in [a package](https://github.com/facebook/react-native/blob/1e8f3b11027fe0a7514b4fc97d0798d3c64bc895/local-cli/link/__fixtures__/android/0.20/MainActivity.java#L37) and are eagerly initialized. The startup time of React Native increases with the number of Native Modules, even if some of those Native Modules are never used. Native Modules can be initialized lazily using [LazyReactPackage](https://github.com/facebook/react-native/blob/42146a7a4ad992a3597e07ead3aafdc36d58ac26/ReactAndroid/src/main/java/com/facebook/react/LazyReactPackage.java) but this does not work in the Open Source repo as the annotation processor [ReactModuleSpecProcessor](https://github.com/facebook/react-native/blob/42146a7a4ad992a3597e07ead3aafdc36d58ac26/ReactAndroid/src/main/java/com/facebook/react/module/processing/ReactModuleSpecProcessor.java) does not run with Gradle yet. Note that there was [a PR to solve this](https://github.com/facebook/react-native/pull/10084), but it was not merged. 14 | 15 | 2. There is no simple way to check if the Native Modules that JavaScript calls are actually included in the native app. With over the air updates, there is no easy way to check if a newer version of JavaScript calls the right method with the correct set of arguments in Native Module. 16 | 17 | 3. Native Modules are always singleton and their lifecycle is typically tied to the lifetime of the bridge. This issue is compounded in brownfield apps where the React Native bridge may start and shut down multiple times. 18 | 19 | 4. During the startup process, Native Modules are typically specified in [multiple packages](https://github.com/facebook/react-native/blob/b938cd524a20c239a5d67e4a1150cd19e00e45ba/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackage.java). We then [iterate](https://github.com/facebook/react-native/blob/407e033b34b6afa0ea96ed72f16cd164d572e911/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java#L1132) over the list [multiple times](https://github.com/facebook/react-native/blob/617e25d9b5cb10cfc6842eca62ff22d39eefcf7b/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModuleRegistry.java#L46) before we finally give the bridge a [list of Native Modules](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java#L124). This does not need to happen at runtime. 20 | 21 | 5. The actual methods and constants of a Native Module are [computed during runtime](https://github.com/facebook/react-native/blob/master/ReactCommon/cxxreact/ModuleRegistry.cpp#L81) using [reflection](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaModuleWrapper.java#L75). This can also be done using build time. The individual method calls themselves are sent over a message queue. 22 | 23 | ## Background 24 | 25 | ### JavaScript Interface 26 | The communication between JavaScript and the VM is being standardized using a JavaScript Interface (__JSI__). [Fabric](https://github.com/react-native-community/discussions-and-proposals/issues/4) uses JSI to [expose methods](https://github.com/facebook/react-native/blob/5d9326be29be8688f2238c72c18a9037f983c77d/ReactAndroid/src/main/java/com/facebook/react/fabric/jsc/jni/FabricJSCBinding.cpp#L264) to JavaScript code. Using JSI, JavaScript can hold reference to C++ Host Objects and invoke methods on them. 27 | 28 | ### Native Modules 29 | > [TODO] - A detailed section on how native modules work today. 30 | 31 | ## Detailed design 32 | 33 | ## Defining Native Modules 34 | Internally, we use flow types to define the Native Modules and their method and signatures (also called "shape of Native Modules"). This is then used to generate Java and ObjC classes with method stubs with matching signatures, which can be extended for the actual implementation. We plan to now generate C++ classes with the same shape, that can then be used to call into the Java/ObjC implementations. 35 | 36 | ## Initial Processing 37 | All initial processing will be removed as C++ now knows the shape of Native Modules. A proxy similar to the [NativeModuleProxy](https://github.com/facebook/react-native/blob/da7873563bff945086a70306cc25fa4c048bb84b/ReactCommon/cxxreact/JSCExecutor.cpp#L141) will be defined in C++ and [exposed in JavaScript](https://github.com/facebook/react-native/blob/a93e281428f47ba355ba79cda3e98ca7da677636/Libraries/BatchedBridge/NativeModules.js#L152). The initialization can typically happen when the RootView is initialized, but once we are independent of the bridge, this can also happen at other times. 38 | 39 | ## Invoking methods on Native Module 40 | When the JavaScript code like `require('NativeModule').DeviceInfoModule` is called, the getter on the proxy is invoked. It would return a reference to object generated in C++ with the shape of the Native Module. Method calls on this reference would simply call over to Java or ObjC. The actual call may also need to have checks to ensure the type and count of arguments. 41 | 42 | > [TODO] - A work in process. 43 | 44 | ## Open Questions 45 | 1. How would the C++ object corresponding to the shape of a Native Module know the Java class (for example com.facebook.react.nativemodule.DeviceInfo) that it needs to call. Does this need to be a switch/case or a map in Java/ObjC that is constructed manually? Would this be done using BUCK dependencies? 46 | 2. Today, native modules usually take `ReactApplicationContext` as a parameter when they are constructed, but they can also be constructed in other ways like using a builder, or multiple parameters in the constructor. How would this be enforced? 47 | 3. How would the C++ code gen happen in Open Source, where BUCK is not used? 48 | 4. Since the generated C++ host objects have the same lifetime of the JS scopes they are referred in, what is the API to tell Java/ObjC when these objects are deallocated? 49 | 5. ReactModule options like `OnBatchCompleteListener` and `hasEagerInitialization` will be removed. Are they needed anymore, if yes - whats the alternative? 50 | 6. This method allows Native Modules to not be singletons. What would this new pattern look like? Would this lead to memory leaks? 51 | 52 | ## Backward Compatibility 53 | 1. It looks like existing native modules do not have to change since they are usually singletons. 54 | -------------------------------------------------------------------------------- /proposals/0013-Extracted-Command-Line-Tools.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Extract CLI from Core 3 | author: 4 | - Mike Grabowski 5 | date: 2018-08-10 6 | --- 7 | 8 | # RFC0013: Extract CLI from Core 9 | 10 | ## Summary 11 | 12 | Extract the current CLI implementation from React Native Core and move it into a third party package. 13 | 14 | ## Basic example 15 | 16 | Command line tools in React Native are split into two, separate pieces. 17 | 18 | First one is the `react-native-cli` package that we prompt users to install globally, for the first time they actually interact with the framework. This package, by the design, is not meant to be frequently updated, which eliminates many annoying issues that global packages are infamous for. 19 | 20 | The second one is `local-cli` package which is the actual source code of the CLI. It is a set of multiple commands, each of them grouped into a standalone module, that are loaded altogether when the CLI is spawned. 21 | 22 | The biggest part of the `local-cli` is its `core`, which is capable of analyzing your source code. It provides a context object for all the commands, that contains necessary information about the location of your source files, available platforms and more. Commands such as `link`, `unlink` or `run-ios` use that information to perform their work. 23 | 24 | This proposal suggests no changes to the end user in its first iteration. We would simply couple new package with React Native version, just like we do with Metro. That makes it possible to still make React Native version specific changes to the CLI itself. 25 | 26 | ## Motivation 27 | 28 | Facebook does not use the CLI provided with React Native, which makes it hard to maintain the project. There is no clear owner and issues / pull requests get stuck in the sea of other, non-CLI related reports. 29 | 30 | It is also hard to keep moving on the CLI as every additional dependency or code change is subject to the heavy review process and sync. 31 | 32 | Extracting it out would be the first step to make React Native CLI agnostic, allowing other tools (including Webpack via Haul) to become first-class citizens and use common design infrastructure. 33 | 34 | ## Detailed design 35 | 36 | The goal of this proposal is to extract the CLI out of the React Native repository into a separate project, called `react-native-cli`, that would become a direct dependency of React Native. It is similar to the extraction process of `Metro`. 37 | 38 | That includes moving out two folders: 39 | - `local-cli`, where business logic of the CLI and all available commands are located 40 | - `react-native-cli`, where global package for running `react-native init` lives 41 | 42 | Development of these two packages would take place under one repository. 43 | 44 | Since `metro` isn't required anywhere else outside of `local-cli` folder (where the business logic of the CLI is located), it would be removed from the React Native dependencies and become the depdendency of newly created `react-native-cli`. 45 | 46 | ## Drawbacks 47 | 48 | Every time the new release of React Native is cut, few dependencies must be updated (`metro` in particular). Due to the way Facebook develops their products internally using monorepo, the version of `metro` must be set manually by the Metro team right after they release their version to the `npm` registry. 49 | 50 | After extracting out `react-native-cli` to a separate repository and `metro` becoming its dependency, Metro team would have to update the version inside that project instead. React Native CLI maintainers would then make sure to update the versions when cutting new release. 51 | 52 | ## Alternatives 53 | 54 | There's Haul - an open source project by Callstack - in development that uses Webpack instead of Metro to bundle React Native code. It is a different project having different goals. Unfortunately, due to tight-coupling of `local-cli` with React Native, it became hard to integrate these two together. 55 | 56 | ## Adoption strategy 57 | 58 | The CLI would roll out as an independent package automatically with one of the upcoming React Native versions. 59 | 60 | ## How we teach this 61 | 62 | Clear communication in the changelog. Printed instructions on how to fill in bug report right after the CLI ends up with non-zero exit code. 63 | -------------------------------------------------------------------------------- /proposals/0018-cocoapods-support-improvements.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: CocoaPods Support Improvements 3 | author: 4 | - Orta Therox 5 | - Eloy Durán 6 | date: 2018-08-15 7 | --- 8 | 9 | # RFC0018: CocoaPods Support Improvements 10 | 11 | ## Summary 12 | 13 | Simplify CocoaPods support in React Native, by reducing the differences between how CocoaPods maps React Native into the existing set of Xcode projects. 14 | 15 | ## Basic example 16 | 17 | CocoaPods support in React Native is a tad tricky, because it’s trying to map a complex set of Xcode projects into a single dependency. The Podspec for React Native does a lot of work under the hood at ~300 LOC. This is, in part, because we use a CocoaPods abstraction called subspecs to consolidate out the React Native library into one single library. 18 | 19 | If we split the `React.podspec` into many podspecs, one per Xcode project. Roughly ~10ish Podspecs per React Native release. These would match up one-to-one to the Xcode projects so that when CocoaPods support is broken in React Native, an error report would make it obvious which part of the project is broken. 20 | 21 | This means we can also move React Native and we can get CocoaPods support back in CI. This route allows CocoaPods support to be tested without network access (all the required information would be inside the same) 22 | 23 | The CocoaPods React dependency would then depend on React-ART, and React-RCTSettings etc. 24 | 25 | ## Motivation 26 | 27 | For teams adding React Native to existing apps CocoaPods support let's RN be treated as a dependency like all of the other ones. CocoaPods is built with a lot of escape valves for consumers to fix issues at runtime (you see people passing around `post_install` [fixes](https://github.com/facebook/react-native/issues/20182#issuecomment-409131862) for example, and I built a [CocoaPods plugin](https://github.com/orta/cocoapods-fix-react-native) to try consolidate them all) 28 | 29 | I think one of the a key reasons for the drift between the CocoaPods support and the Xcode projects is because they're not mapped together. 30 | 31 | ## Detailed design 32 | 33 | ```sh 34 | rm React.podspec 35 | 36 | touch React/React.podspec 37 | pod spec lint React/React.podspec 38 | 39 | touch Libraries/ART/React-ART.podspec 40 | touch RNTester/React-RNTester.podspec 41 | touch Libraries/Blob/React-RCTBlob.podspec 42 | # etc 43 | ``` 44 | 45 | Implementing that is reasonably straight forwards. Then we have two ideas about how the Podspecs can be distributed. 46 | 47 | - Podspecs are shipped to CocoaPods trunk when a release is deployed. This is the simplest for library consumers, but a bit more taxing on release deployment. It must have been discussed before, but they were classed as being deprecated. I'm open for this RFC to be about bringing that back. 48 | 49 | - Or... The React Native repo is turned into a Podspecs Repo. This would mean making a Specs folder in the root of the react-native repo, and putting in the CocoaPods Podspecs. People using CocoaPods would include React Native at the top of their Podfiles like so: 50 | 51 | ```ruby 52 | source 'https://github.com/facebook/react-native.git' 53 | source 'https://github.com/CocoaPods/Specs.git' 54 | 55 | pod "React" 56 | pod "React-Devtools" 57 | ``` 58 | 59 | The changes would convert the React Native repo to act like a specs repo: 60 | 61 | ``` 62 | $ ls . 63 | 64 | [... as it is today] 65 | Specs 66 | [... as it is today] 67 | 68 | $ tree Specs 69 | 70 | React 71 | ├── 0.57.0 72 | │ └── React.podspec.json 73 | └── 0.57.1 74 | └── React.podspec.json 75 | React-ART 76 | ├── 0.57.0 77 | └── React-ART.podspec.json 78 | └── 0.57.1 79 | └── ... 80 | React-RCTSettings 81 | ├── 0.57.0 82 | └── 0.57.1 83 | Yoga 84 | ├── 0.45.0-rc.2.React 85 | └── 0.48.4.React 86 | [.. for all the specs] 87 | ``` 88 | 89 | ## Drawbacks 90 | 91 | Why should we _not_ do this? Please consider: 92 | 93 | - This adds more files for CocoaPods support in the React Native repo, but it puts each one next to the Xcodeproj it represents. 94 | - The "React Native repo as Specs repo" adds a folder called "Specs" in the root, which is confusing for JS/Android folk. We can add support into CocoaPods to recognize "Podspecs" instead also. 95 | - If you were already separating your JS repo from your app code, then you would need to change your Podfile. But this means you don't have to host these Podspecs yourself (or [use Artsy's](https://github.com/artsy/specs)) 96 | 97 | 98 | ## Alternatives 99 | 100 | - CocoaPods support could be handled by [shipping binaries](https://github.com/react-native-community/discussions-and-proposals/issues/15) of React Native to clients. Personally, I prefer to be working with the source code for ease of forkability and debugging. 101 | 102 | ## Adoption strategy 103 | 104 | Shouldn't be major, a paragraph or two in the blog post for the version that first supports it and an update to the docs page for integrating with an existing app. 105 | 106 | ## How we teach this 107 | 108 | Shouldn't be an issue here. 109 | 110 | ## Unresolved questions 111 | 112 | The biggest call is: 113 | 114 | - Submitting the Podspecs to CocoaPods on a deploy, or 115 | - Turning the "React Native repo into a Spec repo" 116 | 117 | If anyone can talk to the original reasons for deprecating trunk support? then I can give a better opinion about which makes the most sense. The first one is simpler for everyone, but in 2016 the trunk support was [deprecated](http://cocoapods.org/pods/React). 118 | -------------------------------------------------------------------------------- /proposals/0036-Official-Docker.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Official Android Docker for react native 3 | author: 4 | - Daniel Geng 5 | date: 2018-10-5 6 | --- 7 | 8 | # RFC0036: Official Android Docker for React Native 9 | 10 | ## Summary 11 | 12 | Provide an official docker to the community and make the ci easier. 13 | 14 | ## Basic example 15 | 16 | Not related. 17 | 18 | ## Motivation 19 | 20 | Docker is a fantastic technology. With this, react native users can easily integrate ci to their code. 21 | Also you can easily debug react native code without setting up all the tools needed like android sdk and nodejs. 22 | Like if you want to build RNTester after you make some change, you can just use something like this: 23 | ```bash 24 | docker run --rm --name hei -v $PWD:/pwd -w /pwd gengjiawen/react-native /bin/sh -c "./gradlew RNTester:android:app:assembleRelease" 25 | ``` 26 | 27 | ## Detailed design 28 | 29 | I have an wip [pr](https://github.com/facebook/react-native/pull/21477), things need to do 30 | * Fix current docker file 31 | * Add publish docker script file 32 | * Hook publish docker script when release a new version 33 | 34 | ## Drawbacks 35 | 36 | Maybe a little cumbersome when update related android tools because now it use a prebuilt docker image. 37 | But if we build the image in the circle ci, the build time will became longer. 38 | 39 | ## Alternatives 40 | 41 | There are many android docker, but most of them lacks node ,ndk or buck(Although I don't use it, but some people do). 42 | Also react native developers needn't to find the right docker since we already provide it. 43 | 44 | ## Adoption strategy 45 | React Native developers may need to familiar the basics of docker and ci, but this became much easier since 46 | much more people are using it. 47 | 48 | ## How we teach this 49 | 50 | We should add this to react native website and maybe add it to template and provide an example to demo this. 51 | 52 | ## Unresolved questions 53 | 54 | 55 | -------------------------------------------------------------------------------- /proposals/0054-a11y-roles-states-improvements.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Improvements to accessibilityRole and accessibilityStates 3 | author: 4 | - Marc Mulcahy 5 | date: 2019-02-06 6 | --- 7 | 8 | # RFC0054: Improvements to `accessibilityRole` and `accessibilityStates` 9 | 10 | ## Summary 11 | 12 | Some brilliant work was begun to add cross platform support for accessibility roles and states to React Native. We propose to add some additional roles and states, as well as extend the implementation on Android and Fire OS. 13 | 14 | ## Basic example 15 | 16 | With the current set of roles, it is not possible to describe a checkbox. These changes would enable this scenario, among other things: 17 | 18 | 21 | Show Password 22 | 23 | 24 | ## Motivation 25 | 26 | When developers build components in JavaScript, they need the ability to express the role and current state(s) of the component to assistive technologies running on the platform. 27 | 28 | ## Detailed design 29 | 30 | ### New Roles 31 | 32 | This proposal adds the following roles: 33 | 34 | - alert 35 | - checkbox 36 | - combobox 37 | - editabletext 38 | - menu 39 | - menubar 40 | - menuitem 41 | - progressbar 42 | - radiobutton 43 | - radiogroup 44 | - scrollbar 45 | - spinbutton 46 | - switch 47 | - tab 48 | - tablist 49 | - timer 50 | - toolbar 51 | 52 | ### New States 53 | 54 | This proposal adds the following states: 55 | 56 | - on 57 | - off 58 | - checked 59 | - unchecked 60 | - busy 61 | - expanded 62 | - collapsed 63 | - hasPopup 64 | 65 | ### Fallback Mechanism for Roles 66 | 67 | There are several roles which don't have native analogs on a given platform. For such roles, a fallback mechanism will be used. 68 | 69 | #### Android 70 | 71 | The fallback mechanism is already in place on Android. For roles which don't have standard Android view analogs, the class name of the AccessibilityNodeInfo is set to the class name of the closest native Android view type, and the roleDescription extra is set to a localized textual description of the role. 72 | 73 | ### Fire OS 74 | 75 | For Fire OS, we will always embed the role as a key/value pair in the AccessibilityNodeInfo's extra bundle. 76 | 77 | key: com.amazon.accessibility.role 78 | value: the role string 79 | 80 | The role string should not be localized-- it should be one of the constants defined above, or in the existing documentation. This will allow assistive technologies on Fire OS to consume the role directly. 81 | 82 | #### iOS 83 | 84 | For roles which don't have a corresponding iOS accessibilityTrait, we recommend appending a localized version of the role description to the accessibilityValue of the component. 85 | 86 | ### Additional States Implementation Notes 87 | 88 | Android has slightly more robust state support than does iOS. The following states can be represented with Android'd standard accessibility API: 89 | 90 | - checked 91 | - unchecked 92 | - expanded 93 | - collapsed 94 | - hasPopup 95 | 96 | We will append a localized description of other states to the component's content description. 97 | 98 | on iOS, a localized description of states which do not have corresponding accessibilityTraits will be appended to the component's accessibilityValue. 99 | 100 | ## Drawbacks 101 | 102 | Supporting these additional roles and states will necessarily make the platform accessibility implementations a bit more complex, especially when supporting roles and states which have no native analog on a given platform. 103 | 104 | We do not see this impacting any existing code. Developers who choose to use the new roles and states will get improved accessibility functionality. Those who choose not to will see no change in the behavior of their existing code. 105 | 106 | ## Alternatives 107 | 108 | The only alternative is to recommend that developers append the role and state information to the text of the accessibility label. This does not allow a disabled user to control how much, and in what order, they hear information about a component. It also does not support compact rendering of role and state information in braille. It also requires localization effort in each component which employs it. 109 | 110 | ## Adoption strategy 111 | 112 | We should document the additional roles and states as part of the official accessibility API documentation. Developers can then start using them if they choose. 113 | 114 | ## How we teach this 115 | 116 | The attempt with this proposal is to bring React Native accessibility support one step closer to generally accepted accessibility idioms and practices as specified by standards such as ARIA. As such, we believe this will make it easier for developers familiar with accessibility on the web or other platforms to relate React Native's accessibility support to what they already know. 117 | 118 | ## Unresolved questions 119 | 120 | - Roles imply supported states and behaviors. For example, checkboxes imply the checked state, and the ability to be toggled. Radio groups typically only allow one child to be selected, etc. When a component specifies its role, should this programmatically require the developer to implement certain behaviors? Alternatively, what mechanisms exist to present warnings during compile time for missing behaviors? 121 | -------------------------------------------------------------------------------- /proposals/0055-a11y-actions.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Accessibility Actions Support 3 | author: 4 | - Marc Mulcahy 5 | date: 2018-10-31 6 | --- 7 | 8 | # RFC0055: Accessibility Actions Support 9 | 10 | ## Summary 11 | 12 | Custom components often require interactions beyond simple touches. Programatic access to these interactions must be provided to allow disabled users to perform them. 13 | 14 | ## Basic example 15 | 16 | Consider the simple example of a custom slider. The newly expanded accessibilityRole property allows us to indicate that the component is a slider in a cross-platform way. However, the blind or motor impaired user can't adjust the slider, since a gesture other than a single tap is required to do so. 17 | 18 | ## Motivation 19 | 20 | The example above is one use case, but there are several common patterns and use cases which require custom action support. Here are a few examples: 21 | 22 | * Adjustable controls (such as sliders) 23 | * Scrollable containers where the scrolling is not handled natively 24 | * Extra swipe actions in a list (swipe right to delete an email message for example) 25 | 26 | ## Detailed design 27 | 28 | This proposal adds an additional accessibility-related property called accessibilityActions to View. The value of this property is a list of accessibility action objects. Each action contains the following properties: 29 | 30 | * name: a string name for the action. Note that a pre-defined set of standard actions is supported, but components can also define their own custom actions. 31 | * description: a localized description of the action which can be presented to the user to describe what will happen when the action is performed. 32 | * function: the function to call when the assistive technology requests this action to be performed. This function should return true if the action is performed, and false if not. 33 | 34 | Standard action names include: 35 | 36 | * activate: activate the item (typically accomplished by double tapping the item when using a screen reader) 37 | * longpress: Long presses anywhere inside the component 38 | * scrollforward: Scrolls the component forward one screen full 39 | * scrollbackward: Scrolls the component backward one screen full 40 | * dismiss: Dismisses the component 41 | * magictap: on iOS, user double taps with two fingers while accessibility focus is on the component. Not available on Android. 42 | * adjustup: Adjusts component up 43 | * adjustdown: adjust component down 44 | * expand: Expands the component 45 | * collapse: Collapses the component 46 | * copy: copies content in the component to the clipboard 47 | * cut: cuts content in the component to the clipboard 48 | * paste: pastes clipboard contents into this component 49 | * setvalue: sets the value of this component (typically used to adjust sliders, etc.) 50 | 51 | ### Implementation Notes 52 | 53 | #### Android/Fire OS 54 | 55 | A custom AccessibilityDelegate will handle custom actions which are added to React Native components. This concept maps fairly directly to Android's notion of AccessibilityActions. 56 | 57 | #### iOS 58 | 59 | React Native actions will be implemented on iOS via the UIAccessibilityAction informal protocol. Standard actions will be used to support React Native standard actions where appropriate. iOS custom actions will be used to support React Native custom accessibility actions. 60 | 61 | ## Drawbacks 62 | 63 | * Difficult for new developers to know what actions they should support. 64 | * Localization of action descriptions seems problematic and hard to maintain. 65 | * Any performance concerns making the action functions synchronous? 66 | 67 | ## Alternatives 68 | 69 | For native components, the platform often provides the necessary actions or other support to allow assistive technologies to manipulate the components. This is only required for custom components built entirely in JavaScript. But for such components, I don't know of another solution. 70 | 71 | ## Adoption strategy 72 | 73 | This is not a breaking change. Components can migrate to the new API as needed. 74 | 75 | ## How we teach this 76 | 77 | The simple rule of thumb is that if your component can be manipulated in ways other than a simple touch, it needs custom action support. The tricky bit to teach will be exactly what actions should you support, especially for scrolling containers. 78 | 79 | ## Unresolved questions 80 | 81 | * What is the most efficient way to localize the description strings? Should they be IDs rather than actual strings? 82 | * How will we add custom actions to native components? 83 | * What additional standard actions should be supported? 84 | * When an action supports arguments, how should we communicate the meaning of those arguments to assistive technologies? Do we rely on the assistive technologies knowing about particular actions and their arguments out of band? 85 | * Should we namespace actions to avoid collisions? For example, if you're defining your own copy action, should the name be "com.example.copy"? 86 | -------------------------------------------------------------------------------- /proposals/0480-react-native-monorepo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: React Native as a monorepo 3 | author: 4 | - Lorenzo Sciandra 5 | - Tommy Nguyen 6 | - Nicola Corti 7 | date: 2022-05-18 8 | --- 9 | 10 | # RFC0480: React Native as a monorepo 11 | 12 | ## Summary 13 | 14 | This proposal is not much as in introducing something completely new, but more to discuss a solution to an existing problem. To put simply, the current shape of the `react-native` codebase hosted in GitHub is lacking structure and consistency and this is leading to a number of issues (detailed below). 15 | 16 | This proposal is about re-shaping the existing codebase on GitHub into what is commonly expected of a monorepo in the JavaScript ecosystem (see, for example, [Babel.js](https://github.com/babel/babel) or [Next.js](https://github.com/vercel/next.js)): consistent versioning, naming and tooling. 17 | 18 | ### Table of Content 19 | 20 | - [Motivation](#motivation) 21 | - [A IRL scenario of this being a problem: `react-native-codegen` and RN 68](#a-irl-scenario-of-this-being-a-problem-react-native-codegen-and-rn-68) 22 | - [Detailed design](#detailed-design) 23 | - [The proposal](#the-proposal) 24 | - [Going the extra mile: Hermes](#going-the-extra-mile-hermes) 25 | - [Implementation detail considerations](#implementation-detail-considerations) 26 | - [Other considerations](#other-considerations) 27 | - [Plan of action](#plan-of-action) 28 | - [Drawbacks](#drawbacks) 29 | - [Alternatives](#alternatives) 30 | - [Adoption strategy](#adoption-strategy) 31 | - [How we teach this](#how-we-teach-this) 32 | - [Future work](#future-work) 33 | - [Unresolved questions](#unresolved-questions) 34 | 35 | ## Motivation 36 | 37 | To quickly explain the motivation behind this proposal, here's the current shape of the React Native codebase hosted on GitHub and corrispective npm packages: 38 | 39 | ![current status of the react-native GitHub codebase](./assets/0006-current-status.png "Current Status") 40 | 41 | It should quickly become apparent that there are a few discrepancies: 42 | 43 | - naming convention is not consistent (ex. `@react-native/assets`, `react-native-codegen`, `@react-native-community/eslint-plugin`) 44 | - semver versioning is not consistent (certain packages are on a major version such as `@react-native/assets`, others are on a patch level such as `@react-native/babel-plugin-codegen`) 45 | - semver is not aligned or coordinated with the `react-native` package semver 46 | - no changelogs for any of these other packages 47 | 48 | On top of this, there are some more substantial issues: 49 | 50 | - releasing a new version of any package that is not the main `react-native` one requires an engineer manually releasing it via CLI on a local machine (which is potentially also a security issue, given how some of these packages are owned by members of the community) 51 | 52 | - which also means that the same person then needs to manually bump the dependency in other parts of the codebase, since they are fixed. For example, see how root level package.json depends on `"@react-native/polyfills": "2.0.0",` ([permalink](https://github.com/facebook/react-native/blob/b331229b06dde31ff92091a163cfabb030082925/package.json#L108)). 53 | - this also affects the nightlies cycle: the only package that gets nightly releases is `react-native`, and no other packages (which implies a high risk of the nightly being broken because the rest of the toolchain not having a corrispective release). 54 | 55 | - because of the root `package.json` being not just the `react-native` package but also the root/CI for the repo, during the release script for `react-native` there's some 🪄magic🪄 that happens to copy over some dependencies from `repo-config/package.json` into the root one (see [this commit](https://github.com/facebook/react-native/commit/6efb51777c620a95e457488fbc7df5c272b3c695#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519)). It's a weird pattern that is undocumented and I'm scared of the issues it creates, since (as all the others) `repo-config/package.json` is manually maintained. 56 | 57 | - for example, 0.69.0-rc0 was still depending on React 17 in the 0.69 branch; it was addressed afterwards with [this commit](https://github.com/facebook/react-native/commit/a862d9294bf22ba2304fe5d742010dc210a2ef5a) 58 | 59 | - because this configuration is mostly "github repo only", there's an high risk of things getting outdated or changes slipping between the cracks (such as the `repo-config` example mentioned there), and only being addressed after someone hits them as a third party consumer. 60 | 61 | - The current setup is not encouraging modularization (that makes situations like the [RFC about ios and android packages](https://github.com/react-native-community/discussions-and-proposals/pull/49) harder). Essentially creating a new `@react-native/*` NPM package today is over-complicated and the infrastructure is not able to handle this properly. 62 | 63 | - This setup makes it hard to have consistent testing in the CI: 64 | - there are two different build patterns for [RNTester](https://github.com/facebook/react-native/tree/main/packages/rn-tester) and for [the template](https://github.com/facebook/react-native/tree/main/template). 65 | - template has to do 🪄magic tricks🪄 to simulate an npm package for react-native when testing - [see more here](https://github.com/facebook/react-native/blob/main/scripts/test-manual-e2e.sh#L109). 66 | 67 | ### A IRL scenario of this being a problem: `react-native-codegen` and RN 68 68 | 69 | To clarify further how this current structure negatively affects maintaining the codebase, here's a quick example that has happened relatively recently. 70 | 71 | `react-native-codegen` is one of the packages shown in the graph as one that is on a `0.0.X` versioning. This meant that with RN `0.68.0`, the version of `react-native-codegen` it depended on was the one the codebase was at the time of cutting the `0.68-stable` branch (`0.0.13`). 72 | 73 | After releasing `0.68.0`, it was quickly realised that there was an issue with this version (details are unnecessary) that required a fix; this fix also needed to affect code within the `react-native-codegen` folder. 74 | 75 | Here's the catch: in the time between the cut of `0.68-stable` branch and the release of `0.68.0`, work on the main branch kept on going and by when the fix was needed, `react-native-codegen` was on `0.0.16`. This meant that we needed to apply a 0.68 specific fix on `react-native-codegen` in its code shape in the `0.68-stable` branch, and do a release in such a way that it would only get picked up by RN 68. But because of the way semver works on Node, the only version we could release was `0.0.17` (`0.0.13.1` is not a thing). And it should be clear that releasing an higher version number of a package, that contains older code, is a very bad situation. 76 | 77 | To address this, in the end with the releases team we had to coordinate a triple version number change for `react-native-codegen` so that it would reshape into: 78 | 79 | - `0.68-stable` uses `0.0.17` 80 | - `0.69-stable` uses `0.69.x` 81 | - `main` uses `0.70.x` 82 | 83 | And all of this had to be done manually, and after each version bump for this package, a new version of the 0.68 and 0.69 had to be released with the updated dependency on the new appropriate version. 84 | 85 | This proposal aims to address this problem so that it won't have to be dealt with in the future. 86 | 87 | ## Detailed design 88 | 89 | ### The proposal 90 | 91 | This proposal will seem deceptively simple: to decouple the root level of the package from being both root and `react-native`, to just be the former, and move `react-native` as a package in the `packages/` folder. 92 | 93 | The graph here shows in a bit more detail the end goal, along with a few more details and side-changes that are needed to fully address the current situation: 94 | 95 | ![proposal for the react-native GitHub codebase](./assets/0006-proposal.png "Proposal") 96 | 97 | Reiterating the changes proposed in the graph: 98 | 99 | - we need to move the `react-native` specific code in its own folder within the `packages/` folder. This is the most error prone step to handle, as many paths and variables might have to be modified (for ex. in the CI configurations) to accommodate for this change. 100 | - we have to **rename** some of other packages as shown above, and in this table: 101 | 102 |
103 | Expand table of package.json/npm names 104 | 105 | | old name | new name | 106 | | ------------------------------------- | ---------------------------------- | 107 | | @react-native/assets | @react-native/packager-assets | 108 | | @react-native/babel-plugin-codegen | @react-native/babel-plugin-codegen | 109 | | @react-native-community/eslint-config | @react-native/eslint-config | 110 | | @react-native-community/eslint-plugin | @react-native/eslint-plugin | 111 | | @react-native/normalize-color | @react-native/normalize-colors | 112 | | @react-native/polyfills | @react-native/js-polyfills | 113 | | react-native-codegen | @react-native/codegen | 114 | | react-native-gradle-plugin | @react-native/gradle-plugin | 115 | 116 |
117 | 118 |
119 | Optional: change name of folders 120 | 121 | | old path | new path | 122 | | ---------------------------------------------------------- | ------------------------------------------ | 123 | | react-native/packages/assets | react-native/packages/packager-assets | 124 | | react-native/packages/babel-plugin-codegen | react-native/packages/babel-plugin-codegen | 125 | | react-native/packages/eslint-config-react-native-community | react-native/packages/eslint-config | 126 | | react-native/packages/eslint-plugin-react-native-community | react-native/packages/eslint-plugin | 127 | | react-native/packages/normalize-color | react-native/packages/normalize-colors | 128 | | react-native/packages/polyfills | react-native/packages/js-polyfills | 129 | | react-native/packages/react-native-codegen | react-native/packages/codegen | 130 | | react-native/packages/react-native-gradle-plugin | react-native/packages/gradle-plugin | 131 | | react-native/packages/rn-tester | react-native/packages/tester | 132 | 133 |
134 | 135 | - _(this step is needed to allow to reset the versioning and introduce alignment across the board)_ 136 | 137 | - we will need to release a new version of the packages with the new npm name/org (and version number) 138 | - this will require a ripple effect of renaming also the places in which those packages are consumed, and to the new version, in the rest of the codebase. 139 | - we want to introduce tooling to avoid having to manually release and version packages. 140 | - in particular, we recommend adding the tool [`changeset`](https://github.com/changesets/changesets) to the codebase to handle the release coordination (as in, once 0.70 gets created, all the packages in that branch get versioned to `0.70.x`) and bump packages accordingly when new versions are needed 141 | - as an alternative, another one of Meta's projects in OSS, [Metro](https://github.com/facebook/metro) could be used as an inspiration for how to setup this scenario: it addresses the naming and versioning in the same manner as described here, and it's a project that has a lot of similarities to RN in the fact that it's also a "partial replica of monorepo code" scenario. It uses [Lerna](https://lerna.js.org/). 142 | 143 | In closing this section, we also want to acknowledge how this proposal is deliberately not introducing any high degree of automation or advanced tooling - this is because we are well aware that this repository is but a "partial mirror" of how the react-native code is shaped within the Meta monorepo, and adding more extensive and invasive tooling would require also introducing them to that monorepo. So we opted for the minimal footprint that would be OSS-side only (with the tradeoff of more custom, local code and scripts). 144 | 145 | ### Going the extra mile: Hermes 146 | 147 | An element that is not presented in the graph above is Hermes engine as a package in this repo (ex. `@react-native/hermes-engine`). This is intentional as it's a more complicated subject, but it's interesting to mention, given the recent decision to move Hermes to a "build from source" scenario ([details](https://github.com/reactwg/react-native-new-architecture/discussions/4#discussioncomment-2382960)). 148 | 149 | An interesting option could be to have it yes as a subfolder (via [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules), maybe?) and handle it as all the other packages above (even for versioning & publishing). 150 | 151 | Another option, that would build on top of the (new) existing process, would still rely on git tags on the `facebook/hermes-engine` repo, but would basically "pull that code" within a `/packages/hermes-engine` folder and handle the release process of Hermes (and its build process) inside it, and publish the artifacts & pre-build separately from the main `react-native` node_module. This would help alleviate the problem of the main `react-native` module being too heavy, and re-align Hermes' versioning to the `react-native` one. 152 | 153 | ### Implementation detail considerations 154 | 155 | - Some parts of this work will have to start from Meta's side (see [comments in the other proposal](https://github.com/react-native-community/discussions-and-proposals/pull/49/files#r255135557)): there's a lot of company specific knowledge involved in how the `react-native` repo gets created for GitHub, and in how the code is shaped in the internal monorepo. Also, renaming and pathing will affect the interal codebase so coordination will be needed. 156 | - Since Metro by default doesn't handle symlinks well (see [this issue for details](https://github.com/facebook/metro/issues/1)), it could be that for RN Tester to keep working we might have to add [`@rnx-kit/metro-resolver-symlinks`](https://github.com/microsoft/rnx-kit/tree/main/packages/metro-resolver-symlinks) 157 | - the changelog generator ([`@rnx-kit/rn-changelog-generator`](https://github.com/microsoft/rnx-kit/tree/main/incubator/rn-changelog-generator)) will need to be worked on to accommodate generating changelogs for any/all/some of the packages in the new monorepo structure 158 | - the logic for the release of nightlies will also need to be revisited to account for the new structure (it would be interesting to star evaluating for which packages a new nightly would be needed at which point); to be clear, right now the existing logic only works for the core `react-native` package. 159 | 160 | ### Other considerations 161 | 162 | - we could consired renaming `react-native` into `@react-native/core` but no strong opinion; given how this is the "front-facing" package it might be easier and more digestable for consumers of react-native to just keep stay on the current convention. 163 | - given the many artifacts involved in the react native toolchain for building an app, there's also the need to figure out a more stable and "automatable" via for creating and distributing these assets. For that purpose, a [separate RFC has been set up here](https://github.com/react-native-community/discussions-and-proposals/pull/508). 164 | 165 | ## Plan of action 166 | 167 | After several brainstorming, we envision the work split in those phases: 168 | 169 | _sidenote: all work in the main repo around this effort will be tracked by the label ["Tech: Monorepo"](https://github.com/facebook/react-native/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc+label%3A%22Tech%3A+Monorepo%22)._ 170 | 171 | ### Phase 1 (Package Renaming & Re-versioning) 172 | 173 | Package renaming & versions alignment. We are going to track this via an umbrella issue: 174 | https://github.com/facebook/react-native/issues/34692 175 | 176 | As a rule of thumb, we decide to **not** do folder renaming: it brings little value, at least at this early stage. 177 | 178 | Ideally we should be done with all the renaming by 0.71.x so that we can annonce that this change has happened in the release notes. We don't expect any user facing impact as users should depend only on `react-native`. Still it's worth to make sure that all the renaming/bumps are bundled together in a single version. 179 | 180 | ### Phase 2 (Automation) 181 | 182 | Once all the versions are aligned, we can work on automation to support: 183 | 184 | - Publishing of all the packages from the CI 185 | - Automating the bumping of the version 186 | 187 | ### Phase 3 (Moving the `react-native` package) 188 | 189 | Once we're done with the setup, we can look into moving the top level package inside `packages/react-native` and have a proper yarn workspace in the top level `package.json` (by also removing the `repo-config/` folder). 190 | 191 | ### Phase 4 (Cleanup) 192 | 193 | Once we're done with the full monorepo setup, we'll into follow-up tasks such as: 194 | 195 | - Deprecating older packages on NPM (those that have been renamed) 196 | - Remaing folders, for those we believe we'll get value out of the rename. 197 | 198 | ## Drawbacks 199 | 200 | - Old open pull requests will likely need to be rebased and re-arranged 201 | - Some of the native build scripts (Gradle, BUCK, Xcode, etc.) and CI scripts and config will need to be updated for the new code locations 202 | 203 | - _(Adding this bullet point to easily allow comments on other drawbacks that might have not been considered)_ 204 | 205 | ## Alternatives 206 | 207 | Since this is basically a fix and not a re-invention, alternatives have not been really explored deeply. Most of the alternative takes boil down to tech choices details in ex. which tool to use to handle the monorepo setup, and not really in the final overall shape of the codebase. 208 | 209 | ## Adoption strategy 210 | 211 | This workstream will span multiple minor releases (see the various steps), so we will need to communicate that each user-facing change as a step to upgrade to the new version. 212 | 213 | Tools like [`dep-check`](https://github.com/microsoft/rnx-kit/tree/main/packages/dep-check) or a codemod should be enough to support edge-cases in which some packages were imported directly. 214 | 215 | No breaking changes are expected, it's just a matter of naming & semver convention re-alignment. 216 | 217 | ## How we teach this 218 | 219 | Nothing to teach, we just need to ensure that the first version to be released after this will have the documentation and blogpost communicate accordingly the new package names (but since `react-native` will stay `react-native`, to many folks this will be transparent). 220 | 221 | Also, the documentation about handling releases will have to be slightly modified if new scripts will get added. 222 | 223 | ## Future work 224 | 225 | We just wanted to point out how this is basically a big refactoring to enable more complex and impactful changes to be more easily done in the subsequent future, such as the integration with Hermes mentioned above or the other proposal ["Move iOS and Android Specific Code to Their Own Packages"](https://github.com/react-native-community/discussions-and-proposals/pull/49). In fact, this proposal addresses [the latest comment](https://github.com/react-native-community/discussions-and-proposals/pull/49#issuecomment-1046073630) on that RFC from [@cortinico](https://github.com/cortinico), in particular resolves points 1 and 2. 226 | 227 | ## Unresolved questions 228 | 229 | _feel free to add something via comments_ 230 | -------------------------------------------------------------------------------- /proposals/0503-rn-versions-lifecycle-support.md: -------------------------------------------------------------------------------- 1 | # RFC0503: React Native Versions Lifecycle & Support 2 | 3 | >As we look for ways to better support the React Native community, we will move towards supporting a limited number of versions of React Native better. 4 | 5 | The React Native Core team is working to strike a balance between the speed of innovation with the amount of regular change to the platform. We understand that each release brings new value and has an adoption cost to the community. 6 | This document describes how we intend to formally balance these concerns and provide clear and consistent support over time. 7 | React Native team will work on best-effort basis to release a new version of React Native at least every four months. And will focus on speeding up the release cycle and put considerable effort into ensuring a seamless upgrade path. 8 | This document describes the level of support we can provide and which set of versions is supported. 9 | 10 | ## Glossary 11 | 12 | Below we are defining terms used in this document: 13 | 14 | * **stable version** - Any version that doesn’t have a -alpha, -beta, -RC postfix in the version name. 15 | * **latest version** - The latest stable version with the highest version number (e.g. 0.68.2). 16 | * The highest version number is defined following the [NPM semver algorithm](https://github.com/npm/node-semver) tagged as "latest". 17 | * **next version** - The next version that hasn’t been fully released yet, and is currently in development/testing (e.g. 0.69.0-RC1). 18 | * **minor series** - A collection of versions (either stable or not stable) sharing the same minor version (e.g. **0.68**.0-RC0, **0.68**.0, **0.68**.1 are all part of the **0.68** minor series). 19 | 20 | ## Which versions are currently supported? 21 | 22 | We’re supporting the **latest version**, and the latest versions from the **two previous minor series.** 23 | We’ll also support the **next version** being developed, which will become stable after its release. 24 | 25 | Versions: 26 | 27 | |Version |Type |Status | 28 | |--- |--- |--- | 29 | |0.71.0-RC0 |Release candidate | Not released yet | 30 | |0.70.0 |Latest stable |In support | 31 | |0.69.5 |Previous minor series |In support | 32 | |0.68.3 |Previous minor series |In support | 33 | |<=0.67.x |Old minor series |Unsupported | 34 | 35 | ## What is the level of support? 36 | 37 | Due to support bandwidth, the React Native team, with the community's help, is looking into issues & PRs opened against one of the supported versions. 38 | 39 | Issues & PRs opened against older versions would be considered only in exceptional cases. Please update your application to one of the supported versions and raise the Issue/PR targeted to that version. 40 | 41 | Issues should contain a [**reproducer**](https://stackoverflow.com/help/minimal-reproducible-example) project regardless of which version they target, for them to be considered. 42 | Issues without a reproducer will require more effort to understand and fix, and are less likely to receive attention. 43 | 44 | At this point in time, we are prioritizing issues that are related to: 45 | 46 | * Latest version of React Native and two previous minor series. 47 | * Use of the New Architecture 48 | * Use of the Hermes Engine 49 | 50 | ## Cherry-Pick Requests 51 | 52 | We’re **accepting cherry-pick requests** for the currently supported versions. A cherry-pick request is the request to include a fix in one of the supported versions and release a new point release with it. 53 | 54 | Cherry-Pick requests should be submitted via the [React Native Releases Working Group](https://github.com/reactwg/react-native-releases/discussions/categories/patches), in the corresponding discussion thread. 55 | 56 | Please note that each cherry-pick request will be assessed and approved individually. Cherry-Pick requests against unsupported versions will be rejected unless they involve security issues. 57 | 58 | ## Security Issues 59 | 60 | Security issues should follow our issue report policy [described here](https://reactnative.dev/contributing/overview#security-bugs). 61 | Reports for security issues on unsupported versions will handed on case by case basis when deciding if a new version needs to be released. 62 | 63 | ## Licence 64 | 65 | React Native is open-source software distributed under the **MIT license**. Software is provided "as is" without warranty. 66 | -------------------------------------------------------------------------------- /proposals/0508-out-of-npm-artifacts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Out-of-NPM package solution for React Native Artifacts 3 | author: 4 | - Nicola Corti 5 | date: 2022-09-09 6 | --- 7 | 8 | # RFC: out-of-NPM package solution for React Native Artifacts 9 | 10 | ## Summary 11 | 12 | The `react-native` NPM package unpacked size is now 126 Mb. We’re close to hit the NPM package size limit. 13 | We need to find a solution to store native artifacts in the long run. 14 | 15 | ## Motivation 16 | 17 | With React Native 0.69, the `react-native` NPM package unpacked size is now 126 Mb. 18 | React Native 0.68 had an unpacked size of 35.6 MB. 19 | 20 | We’re close to hit the NPM package limit and we were already forced to remove Hermes debug symbols for Android to ship the package to NPM. 21 | 22 | Publishing a ~250Mb NPM package is failing with: 23 | 24 | ``` 25 | `npm notice 26 | npm ERR! code E413 27 | npm ERR! 413 Payload Too Large - PUT `[`https://registry.npmjs.org/tfjs-node-lambda-releases`](https://registry.npmjs.org/tfjs-node-lambda-releases)` - Payload Too Large 28 | Error: Process completed with exit code 1.` 29 | ``` 30 | 31 | Essentially NPM is trying to Base64 the package in memory and publishing it to the NPM registry with an HTTP `PUT`. 32 | This is failing as the webserver received a too long payload. More on this here [https://github.com/npm/npm/issues/12750](https://github.com/npm/npm/issues/12750) 33 | 34 | We’re particularly hit by this problem as we're shipping native built libraries inside a NPM package. 35 | 36 | The biggest offender in terms of size are: 37 | 38 | * the `/android` folder which contains prebuilt for both `react-native` and `hermes-engine` used by Android Users on the Old Architecture (which are not building RN or Hermes from source) - ~66Mb 39 | * The `/android` folder is essentially a Maven Local repository that is following the typical Maven Folder structure `com/facebook/react/react-native` follows the `/` 40 | * the `/sdks ` folder which contains prebuilt `hermesc` for the Hermes Compiler - ~43Mb 41 | 42 | ![react-native npm package size graph](/assets/npmsizegraph.png) 43 | 44 | Having all the artifacts shipped inside a single NPM package, has also the side effect of forcing all users to re-downloading the same ~100Mb archive even if they’re not using some of the features (e.g. you’ll be downloading the Android archives even if you’re just building an iOS app). 45 | 46 | ## Overview of current artifacts 47 | 48 | In order to have an holistic overview of which artifacts we have at the moment and where they live, let’s walk through each of them: 49 | 50 | ### The React Native Android Archive 51 | 52 | Currently we ship a prebuilt version of React Android inside the `react-native` NPM package. The prebuilt is located inside the `android` folder and needs to follow this structure: 53 | 54 | ``` 55 | // Checksum files have been removed for brevity. 56 | android 57 | └── com 58 | └── facebook 59 | └── react 60 | └── react-native 61 | ├── 0.70.0 62 | │ ├── react-native-0.70.0-debug-sources.jar 63 | │ ├── react-native-0.70.0-debug.aar 64 | │ ├── react-native-0.70.0-release-sources.jar 65 | │ ├── react-native-0.70.0-release.aar 66 | │ ├── react-native-0.70.0.module 67 | │ └── react-native-0.70.0.pom 68 | ├── maven-metadata.xml 69 | ├── maven-metadata.xml.md5 70 | ├── maven-metadata.xml.sha1 71 | ├── maven-metadata.xml.sha256 72 | └── maven-metadata.xml.sha512 73 | ``` 74 | 75 | The `android` folder is effectively a Maven Repository which follows the [official repository layout](https://cwiki.apache.org/confluence/display/MAVEN/Remote+repository+layout). The `.module` file is a [Gradle Module Metadata](https://docs.gradle.org/current/userguide/publishing_gradle_module_metadata.html) file. It allows to publish two variants for debug and release. 76 | The .aar files contain the Android compiled bytecode for React Native, alongside native libraries (.so). 77 | 78 | At this stage, debug symbols for React Native are not distributed (also for the `react-native-0.70.0-debug.aar`) due to constraints in size for the NPM package. Similarly, prefab support is not enabled (i.e. headers are not distributed, libraries can’t depend on native libraries directly and are forced to unzip the .aar manully - See [https://github.com/react-native-community/discussions-and-proposals/issues/423](https://github.com/react-native-community/discussions-and-proposals/issues/423)). 79 | 80 | The `-sources.jar` file contains Java/Kotlin sources used by IDEs to offer code visualization support. 81 | Alongside those files, each file is distribute with its own checksums (.md5, .sha1, .sha256, .sha512). 82 | GPG Signatures for those files are not distributed (i.e. `.asc` files). 83 | 84 | Please note that the files needs to follow the repository layout to properly be consumed. 85 | 86 | ### The Hermes Android Archive 87 | 88 | With [Bundled Hermes](https://reactnative.dev/architecture/bundled-hermes), the prebuilt version of Hermes have been moved inside the `react-native` NPM package. They’re located inside the `android` folder similarly to:[The React Native Android Archive](#the-react-native-android-archive) 89 | 90 | ``` 91 | // Checksum files have been removed for brevity. 92 | android 93 | └── com 94 | └── facebook 95 | └── react 96 | └── hermes-engine 97 | ├── 0.70.0 98 | │ ├── hermes-engine-0.70.0-debug-sources.jar 99 | │ ├── hermes-engine-0.70.0-debug.aar 100 | │ ├── hermes-engine-0.70.0-release-sources.jar 101 | │ ├── hermes-engine-0.70.0-release.aar 102 | │ ├── hermes-engine-0.70.0.module 103 | │ └── hermes-engine-0.70.0.pom 104 | ├── maven-metadata.xml 105 | ├── maven-metadata.xml.md5 106 | ├── maven-metadata.xml.sha1 107 | ├── maven-metadata.xml.sha256 108 | └── maven-metadata.xml.sha512 109 | ``` 110 | 111 | 112 | Due to limitation on the NPM package size, we’ve been forced to **remove the debug symbols & disable prefab for Hermes** (see [https://github.com/facebook/react-native/pull/33439](https://github.com/facebook/react-native/pull/33439)) from the `react-native` NPM package. 113 | 114 | This had a couple of negative side effects: 115 | 116 | * Android Users **on New Architecture** could **not** use a pre-built of Hermes (as we can’t distribute the prefab). So they’re forced to **build Hermes from source**. 117 | * The impact is that this is creating a discrepancy between the Old and the New Architecture resulting in generally a degraded Developer Experience for the New Architecture. 118 | * Android Users on Old Architecture are forced to download the debug symbols from CircleCI, as they’re beyond 200Mb and can’t be distributed inside the NPM package. 119 | * The impact is that users experiencing native crashes on Hermes don’t see symbolicated stacktraces (on both Old/New Arch). 120 | 121 | ### The Hermesc Binary 122 | 123 | With [Bundled Hermes](https://reactnative.dev/architecture/bundled-hermes), The Hermes Compiler Binary `hermesc` is located inside the `sdks/hermesc` folder of `react-native` 124 | 125 | ``` 126 | sdks 127 | ├── ... 128 | └── hermesc 129 | ├── linux64-bin 130 | │ └── hermesc 131 | ├── osx-bin 132 | │ └── hermesc 133 | └── win64-bin 134 | ├── hermesc.exe 135 | ├── icudt64.dll 136 | ├── icuin64.dll 137 | ├── icuio64.dll 138 | ├── icutest64.dll 139 | ├── icutu64.dll 140 | ├── icuuc64.dll 141 | ├── msvcp140.dll 142 | ├── vcruntime140.dll 143 | └── vcruntime140_1.dll 144 | ``` 145 | 146 | `hermesc` is a binary that should be executed by the host machine at build time when preparing a release version of an app (Android/iOS) that uses Hermes. 147 | 148 | ### The Hermes iOS Tarball 149 | 150 | With [Bundled Hermes](https://reactnative.dev/architecture/bundled-hermes), we publish a prebuilt version of the Hermes Runtime for iOS. This allows users to use Hermes on iOS without having to build it at all (both on Old and New Architecture). 151 | 152 | As the prebuilt tarball is 466 MB, it goes beyond the NPM package limit. 153 | 154 | To overcome this limit, the prebuilt Hermes Tarball is uploaded on Github Releases (example: https://github.com/facebook/react-native/releases/tag/v0.69.4) 155 | 156 | The URL to download the tarball is deterministic and uses the [version key to reference it](https://github.com/facebook/react-native/blob/0b4b7774e2d71259962ed36b7acb5c3989c3be9c/sdks/hermes-engine/hermes-engine.podspec#L39): 157 | 158 | ```ruby 159 | source[:http] = "https://github.com/facebook/react-native/releases/download/v#{version}/hermes-runtime-darwin-v#{version}.tar.gz" 160 | ``` 161 | 162 | ### The React Native Gradle Plugin 163 | 164 | The [React Native Gradle Plugin](https://www.npmjs.com/package/react-native-gradle-plugin) is distributed from sources as a NPM package ([source of the plugin are here](https://github.com/facebook/react-native/tree/main/packages/react-native-gradle-plugin)). 165 | Users are consuming the plugin as an Included build: [codepointer](https://github.com/facebook/react-native/blob/4eec47344e25b2e2cb2e6dbdb3f989ed5b6e2747/template/android/settings.gradle#L4). 166 | 167 | This is impacting the DevX mostly because: 168 | 169 | * Users are forced to recompile the source code of the plugin at every first build (slower build time). 170 | * Users are exposed to build warnings for the plugin, without having a way to hide them. 171 | * Any change to the plugin (i.e. a user touching any of its source file) will cause a whole rebuild of the Android project, due to invalidation of the build classpath. 172 | 173 | Ideally the Gradle Plugin should be bundled following the Maven Repository layout similarly to all the others packages (react-native and hermes-engine). 174 | 175 | ### Other Android/iOS Prebuilt Dependencies 176 | 177 | In the future, we might want to add more library/artifacts, to potentially modularize the project. 178 | An example is the Module Annotation Processor ([see this PR](https://github.com/facebook/react-native/pull/25922)). 179 | 180 | As of today, we don’t have a way to distribute this annotation processor. It should either be distributed from source (similarly to the React Native Gradle Plugin) or as prebuilt (similarly to React Native). 181 | 182 | ## Scenarios to consider 183 | 184 | When solving this issues we should consider several scenarios. Each scenario is distinguished by a different `version` in the top level `package.json` 185 | 186 | * **Building from main** 187 | * Version in the top level package.json: `1000.0.0` 188 | * This is the scenario you’re faced when you `git clone` React Native. 189 | * In this scenario, everything should be **built from source**. There should be no available artifacts. 190 | * **Building a numbered version of React Native** 191 | * **Building a commitly** 192 | * Version in the top level package.json: `1000.0.0-30e54adce` 193 | * This is the scenario our CI is facing on **every commit**. 194 | * Everything should be **built from source**. Artifacts should be available for a user that decides to use this nightly. 195 | * **Building a nightly** 196 | * Version in the top level package.json: `0.0.0-20220816-2027-543e11e5f` 197 | * This is the scenario our CI is facing **every night**. 198 | * Everything should be **built from source**. Artifacts should be available for a user that decides to use this nightly. 199 | * **Building a rc/stable** 200 | * Version in the top level package.json: `0.70.0-rc`.`0` 201 | * This is the scenario our CI is facing on the release branch 202 | * Everything should be **built from source**. Artifacts should be available for a user that decides to use this nightly. 203 | * **Plus:** Release tester on this scenario should be able to test this version of React Native, without having to build everything locally (i.e. by using the commitlies artifacts). 204 | * **Users is using a numbered version of React Native** (nightly, RC or stable) 205 | * Version inside `node_modules/react-native` is: `0.70.0` 206 | * This is the scenario you’re facing if you `npx react-native init ...` 207 | * In this scenario, artifacts should be available for download, ideally with a stable URL which is parametric in the version of React Native. 208 | 209 | ## Solutions 210 | 211 | To address this problem, we should look into moving the binaries from the `react-native` NPM package to a different location. 212 | 213 | In this section we list the possible solutions. 214 | 215 | ### OCI Images on Github Container Registry 216 | 217 | A [comment](https://github.com/react-native-community/discussions-and-proposals/pull/480#issuecomment-1206904964) from [Renaud Chaput](https://github.com/renchap) on the Monorepo RFC, raised this solution to our attention: 218 | 219 | Github offers the possibility to use the [Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) to upload archives without size limits (for public repositories), as long as they conform to the [OCI (Open Container Initiative) specs](https://opencontainers.org/posts/announcements/2021-05-04-oci-dist-spec-v1/#:~:text=The%20OCI%20Distribution%20Spec%20defines,and%20pulling%20of%20container%20images.). This is the same mechanism used by Brew to distribute binaries ([source](https://github.blog/2021-06-21-github-packages-container-registry-generally-available/#dont-just-take-our-word-for-it)). 220 | 221 | Ideally we could create a container, which separate layer per artifact (i.e. one for Hermes iOS tarball, one for React Native Android, etc). Each layer will be a .tar.gz file we can freely populate. 222 | 223 | #### Prototype 224 | 225 | A prototype of this solution is available at [cortinico/space-unlimited-space](https://github.com/cortinico/space-unlimited-space). 226 | The repo will showcase how to publish and retrieve arbitrary tarballs using HTTP without authentication. 227 | 228 | #### Pro 229 | 230 | * Elegant solution which relies on the Github infrastructure and doens’t involve external services (no need to auth, sign, or interact with new services). 231 | * No limits to how much we can upload. 232 | * Potentially we could access the Container Registry API to allow users to download only the layer they need. 233 | 234 | #### Cons 235 | 236 | * Need to write extra infrastructure to handle downloading the OCI images and placing the artifacts in the right folder. 237 | * No caching mechanism out of the box (users with 2 React Native projects, will re-download everything). 238 | * URLs are hard to compose (e.g. https://ghcr.io/v2/cortinico/space-unlimited-space/anakin/blobs/sha256:57b8eee16897b0bb1d00190e99fb722dbaa32ecd1eb70686012ecf814ce329ba). We would need a mapping in place for knowing which blob contains what. 239 | * Plain HTTP access is still not possible, we'll have to pass a `"Authorization: Bearer QQ=="` header, making it hard to consume via CocoaPods or other tool which are expecting HTTP urls ([see here for a curl request](https://github.com/cortinico/space-unlimited-space#consuming-via-http)) 240 | 241 | ### Separate NPM Package 242 | 243 | Ideally we could look into splitting `react-native` into smaller packages: 244 | 245 | * `@react-native/android-prebuilts` will contain the `android/` folder 246 | * `@react-native/hermesc-prebuilts` will contain the `sdks/hermes` folder 247 | 248 | This will partially mitigate the issue as the `android-prebuilts` package will still hit the NPM limit once we include debug symbols. This will require further splitting such as: 249 | 250 | * Per build-type split `android-debug-prebuilts` and `android-release-prebuilts` 251 | * Per library split `react-native-prebuilts` and `hermes-engine-prebuilts` 252 | * Per ABI split `x86_64-prebuilts`, `arm64-v8a-prebuilts` and so on. 253 | 254 | #### Pro 255 | 256 | * Uses a packaging system which is familiar for web developers 257 | * We should be able to reuse most of the publishing pipeline we have in place at the moment 258 | 259 | #### Cons 260 | 261 | * We will be forced to “recompose” the various prebuilts from the several NPM packages to a Maven Local repository inside users’ `node_modules` folder. 262 | * All the users will be downloading all the pre-builts for all the build-types/split/abi whenever they `yarn install`. Therefore users who develop for a single platform incur a download cost for binaries they will never use, vs delaying the download until the specific native build system needs the artifact. 263 | * Having [github.com/facebook/react-native](http://github.com/facebook/react-native) as currently set up (not a proper monorepo) makes really hard to create new NPM packages. 264 | * We will still be having a hard limit on NPM packages so we’ll have to handle further splitting as our library/SDK grows. This is especially more critical as we have more and more C++ code, therefore we’re generating more and more native pre-builts. 265 | 266 | ### Dedicated Maven Repository 267 | 268 | Ideally we could look into publishing the `/android` folder into a remote Maven Repository (most likely Maven Central). 269 | We could re-use a Maven Repository to store artifacts which are not Android-specific (e.g. the Hermes iOS Tarball). 270 | 271 | #### Prototype 272 | 273 | A prototype of how the storing of the Hermes iOS Tarball on Maven would look like is available on: [react-native#34812](https://github.com/facebook/react-native/pull/34812). 274 | 275 | This has been tested against RN Tester iOS on `main` and the tarball download is working correctly. 276 | 277 | #### Pro 278 | 279 | * For Android: Uses a packaging system which is familiar for Android developers and re-uses the already existing caching/perf improvement that are shipping with the platform pipeline. 280 | * A practical benefit of this is that users will have only a local copy of react-native or hermes-engine inside their `~/.gradle` folder instead of having multiple copies, one for every RN project. 281 | * For iOS: We would have stable URLs which can be easily composed with the release version (e.g. https://repo1.maven.org/maven2/com/facebook/react/react-native-artifacts/0.0.1/react-native-artifacts-0.0.1-hermes-ios.tar.gz) 282 | * We will end up using a single solution for both platforms, resulting in reduced maintainance costs. 283 | * Users will download the artifact they need at build time only when needed 284 | * E.g. iOS-only users will benefit of faster `yarn install` and smaller `node_modules` folder. 285 | * Users which are not using Hermes will benefit similarly as well 286 | * We won’t have any limits to the assets we upload and we can freely distribute debug symbols or different variants of our libraries. 287 | * Companies using Maven Proxies (like Nexus) will benefit from this setup out of the box. 288 | * Publishing GPG Signed artifacts will increase the trust users put on our distribution as they could verify that the artifacts haven’t been altered. 289 | * This mechanism is the same used by Flipper and other libraries published by Meta (e.g. FBJNI) which we depends on. 290 | * The React Gradle Plugin can be published on Gradle Portal, where all the other Gradle Plugin live. 291 | 292 | #### Cons 293 | 294 | * ~This solution addressed only the Android/JVM side of the problem~ See the prototype paragraph for a solution that works on both platforms. 295 | * We will have to publish to remote Maven Repositories as part of our RN release process (i.e. a new step inside the CircleCI config, means yet another thing that can be broken) + we’ll have to maintain GPG keys for publishing. 296 | * We’ll have to make sure NPM packages and Maven pubblications are syncronized with a version number. 297 | 298 | ### Relying on CircleCI Artifacts 299 | 300 | Currently, several of our CircleCI jobs are producing and storing artifacts on CircleCI. 301 | CircleCI artifacts have a [retention of 30 days](https://circleci.com/docs/persist-data#managing-network-and-storage-use), which can be optionally extended. 302 | 303 | For nightlies and commitlies, we could setup our infrastructure to fetch artifacts directly from build jobs. CircleCI artifacts have stable URLs and can easily be downloaded without auth tokens. 304 | 305 | #### Pro 306 | 307 | * We reuse most of our storage current infrastructure. We just need to update the CircleCI config to store all the artifacts we need. 308 | 309 | #### Cons 310 | 311 | * We rely on CircleCI status to be up and running for being able to create and run react native apps. 312 | * We need extra logic to properly configure react-native so that the Artifacts URL are populated correctly (i.e. how can a nightly know what’s the build Id of the job that generate it?) 313 | 314 | ### Hybrid Solutions 315 | 316 | We could potentially apply separate solutions for different artifacts, to benefit from platform specific optimizations. 317 | 318 | For example: 319 | 320 | * store hermesc binary, hermes iOS tarbal on a OCI image 321 | * store hermes android archive, react native android archive and Gradle Plugin on Maven Public repositories. 322 | 323 | #### Pro 324 | 325 | * We get the best of both worlds. Optimized caching and security of Maven, while still being able to distribute non maven artifacts. 326 | 327 | #### Cons 328 | 329 | * We need to authenticate and maintain the infra to interact with two distinct systems. 330 | 331 | ### Using Github Releases 332 | 333 | We could extend on Github Releases as we’re doing today for the Hermes iOS tarball. That could work but has several side effects which are making this solution unpractical 334 | 335 | #### Pro 336 | 337 | * Simple solution, with stable URLs which are version specific 338 | 339 | #### Cons 340 | 341 | * Will create a lot of noise in the release space (i.e. we need to create a GIthub release for every nightly). 342 | * Practically unusable for commitlies and release testing (as the release is ‘not there yet’). 343 | 344 | ## Implemented solution 345 | 346 | After having investigated both the OCI and the Maven solution, we decided to move on with the **Dedicated Maven Repository** solution. 347 | 348 | Starting from React Native 0.71.x we'll be shipping the following changes: 349 | 350 | - We'll now distribute **prebuilts** for: 351 | - React Native Android - Coordinates `com.facebook.react:react-android` 352 | - Please note that the previous coordinates `com.facebook.react:react-native` have been voided due to [#35210](https://github.com/facebook/react-native/issues/35210) 353 | - Hermes Engine Android - Coordinates `com.facebook.react:hermes-android` 354 | - Please note that the previous coordinates `com.facebook.react:hermes-engine` have been voided due to [#35210](https://github.com/facebook/react-native/issues/35210) 355 | - Hermes Runtime for iOS - Coordinates `com.facebook.react:react-native-artifacts` 356 | 357 | Prebuilts will be available on 358 | - For **Stable** versions, on Maven Central ([browsable here](https://repo1.maven.org/maven2/com/facebook/react/)) 359 | - For **Nightly** versions,on Sonatype's Snapshot Repository ([browsable here](https://oss.sonatype.org/content/repositories/snapshots/com/facebook/react/)) 360 | 361 | This solution is flexible enough that will allow us to relocate our artifacts to other Maven repositories in the future, if needed. 362 | 363 | The templates for both Android & iOS have been updated to consume the proper prebuilt from the correct URL. 364 | -------------------------------------------------------------------------------- /proposals/0605-lazy-bundling.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Lazy Bundling 3 | author: 4 | - Moti Zilberman 5 | date: 2023-04-03 6 | --- 7 | 8 | # RFC0605: Lazy Bundling 9 | 10 | ## Summary 11 | 12 | Automatically split development bundles at dynamic `import()` boundaries in order to speed up the loading of large apps. 13 | 14 | ## Motivation 15 | 16 | In a large React Native app, the initial JavaScript bundle can be noticeably slow to build and load, as the time required scales with the amount of code in the project. By deferring the bundling of code loaded with `import()`, we can limit the amount of code that needs to be built for any given screen, making it independent of the total size of the app. 17 | 18 | ## Detailed design 19 | 20 | ### Changes to the core bundling algorithm in Metro 21 | 22 | Without lazy bundling, Metro's core bundling algorithm consists of: 23 | 24 | 1. *Resolving* a module - starting with the *entry point* specified by the request. 25 | 2. *Transforming* the module with Babel, which also extracts the module's dependencies (`import` declarations, `require()` calls, `import()` calls). 26 | 1. As an implementation detail, each module is wrapped in a [`define()`](https://github.com/facebook/metro/blob/c8da588a4498d3a8521bb0799143cfa539ed3b50/packages/metro-runtime/src/polyfills/require.js#L123) call. 27 | 2. As an implementation detail, each `import()` call is compiled to a call to [`asyncRequire()`](https://facebook.github.io/metro/docs/configuration/#asyncrequiremodulepath). 28 | 3. Repeating resolution and transformation recursively for all the extracted dependencies. 29 | 4. *Serializing* all transformed modules: 30 | 31 | 1. Assigning each module an ID. 32 | 2. Injecting the IDs of dependencies into the `define()` call generated for each module. 33 | 3. Concatenating all the `define()` calls into a bundle (with an optional source map). 34 | 35 | Lazy bundling will modify steps (3) and (4) above so that: 36 | * The bundler avoids traversing/transforming `import()` dependencies. 37 | * For each `import()` dependency, the serializer adds the dependency's module ID and an *opaque bundle path* to its dependents' `define()` calls. 38 | * Conceptually, the bundle path may be any value that `__loadBundleAsync` (see below) knows how to handle. 39 | * As an implementation detail, the bundle path is a string, and contains a server-relative URL where the imported module can be fetched from Metro. 40 | * The serializer will add a `paths` object to the dependency map, containing a mapping from module IDs to bundle path. 41 | 42 | As a result, the target of an `import()` dependency - along with its transitive dependencies - will not be included in the bundle, unless it's also the target of a static `import` or `require`. 43 | 44 | > **NOTE:** Because lazy bundling does not change the transformer's output, cache entries from a lazy build can be reused in a full (non-lazy) build, and vice versa. This avoids penalizing projects that adopt a mix of lazy and non-lazy bundling. 45 | 46 | ### Changes to the Metro server 47 | 48 | For backwards compatibility, lazy bundling will be **off by default in Metro**, and enabled by the `lazy=true` request parameter. 49 | 50 | **React Native will enable lazy bundling by default** in development bundle requests (`dev=true`). Alternative bundlers used with React Native may ignore the `lazy=true` parameter and emit no calls to `__loadBundleAsync`. 51 | 52 | Within the lifetime of a given Metro server instance, modules will receive stable IDs based on their paths. This will allow the client to skip evaluating copies of the same module that may occur across multiple bundles. 53 | 54 | ### `__loadBundleAsync` in Metro 55 | 56 | The first time an `import()` call is evaluated with a given target, the default `asyncRequire()` implementation in Metro will call a new *framework-defined* global function named `__loadBundleAsync` with that target's bundle path (as produced by the serializer). 57 | 58 | > **NOTE:** The `__loadBundleAsync` identifier will be prefixed with the currently configured [global prefix](https://github.com/facebook/metro/blob/69c8fc707bda418b4eb7aa646ad2887d83e1d3f1/packages/metro-config/src/defaults/index.js#L105), so the correct way to reference it at runtime is ``global[`${__METRO_GLOBAL_PREFIX__}__loadBundleAsync`]``. For simplicity we will continue to call it simply `__loadBundleAsync` in this RFC. 59 | 60 | `__loadBundleAsync` must return a promise that resolves once the bundle has been fetched and evaluated (e.g. with `fetch` and `eval`). 61 | 62 | ```flow 63 | // For lazy bundling: type SerializedBundlePath = string; 64 | declare function __loadBundleAsync(path: SerializedBundlePath): Promise; 65 | ``` 66 | 67 | `__loadBundleAsync` may be called multiple times with the same bundle path, including in parallel. It should implement caching as needed to avoid sending out unnecessary or duplicate requests. It is unspecified how `__loadBundleAsync` should derive its internal cache key from the provided bundle path. 68 | 69 | If there is no `__loadBundleAsync` implementation available, the bundled code may throw a runtime error upon attempting to evaluate an `import()` call. 70 | 71 | > **NOTE:** With the introduction of `__loadBundleAsync`, **we will deprecate the [`asyncRequireModulePath`](https://facebook.github.io/metro/docs/configuration/#asyncrequiremodulepath) option in Metro**. Providing a custom `__loadBundleAsync` implementation is expected to fulfil all current use cases for replacing `asyncRequire` at build time. 72 | 73 | ### `__loadBundleAsync` in React Native 74 | 75 | In development builds, React Native will provide an implementation of `__loadBundleAsync` that fetches a bundle URL from the currently connected Metro server, integrates with Fast Refresh and LogBox, and provides feedback to the developer on the progress of loading a bundle. 76 | 77 | ### Relationship with Fast Refresh 78 | 79 | Fast Refresh will continue to work as expected when multiple bundles are loaded. In particular, thanks to the feature's deep integration with Metro, it will remain possible to change static `import`s to dynamic `import()`s and vice versa with instant feedback. 80 | 81 | ### Relationship with bundle splitting 82 | 83 | The Metro changes described above also *partially* enable more general support for bundle splitting, although that is not the main goal of this RFC. 84 | 85 | Metro integrators may implement a custom bundle splitting solution (e.g. optimizing for chunk size) by: 86 | 87 | 1. Providing a custom serializer that generates custom bundle paths (not necessarily tied to a Metro server). 88 | 2. Providing a custom global implementation of `__loadBundleAsync` to process the bundle paths produced by (1). 89 | 3. Serializing multiple bundles from the same (fully resolved/traversed) dependency graph. 90 | 91 | > **NOTE:** Documenting the experimental APIs in Metro for doing (1) and (3) is outside the scope of this RFC. 92 | 93 | ### Relationship with React Server Components 94 | 95 | While React Server Components are not currently supported in React Native, they remain an area of interest for future development. The bundling infrastructure required to support Server Components has some overlap with what's required for lazy bundling. In particular, resolving a Client Reference in development would likely involve calling `__loadBundleAsync` on a bundle path returned from the server. 96 | 97 | ## Drawbacks 98 | 99 | The key potential drawback is implementation complexity. However, the current proposal minimises this complexity by integrating lazy bundling into the core Metro algorithm (instead of creating a fork), and by keeping the integration surface between React Native and Metro as small as possible (encapsulated in `__loadBundleAsync` and `lazy=true`). 100 | 101 | ## Alternatives 102 | 103 | This RFC is an evolution of an earlier implementation of lazy bundling at Meta, which: 104 | 105 | * Used a non-Fast-Refresh-compatible mechanism for passing bundle paths from the serializer to `asyncRequire`. 106 | * Did not include the `__loadBundleAsync` hook, instead closely coupling Metro to the React Native-specific way of fetching and evaluating bundles. 107 | * Treated lazy bundling as a transform-time config setting instead of a request parameter, resulting in worse caching the inability to build production and development bundles using the same Metro config. 108 | 109 | Apart from these implementation differences, the underlying concept remains the same as what we have been using at Meta since 2019, and we believe it is sound. 110 | 111 | ## Adoption strategy / How we teach this 112 | 113 | Lazy bundling is not a breaking change from the perspective of React Native apps, so we can ship and enable it by default in the course of a single release of React Native. In development, all React Native apps already need to be connected to a working Metro server to support things like Fast Refresh, LogBox symbolication, and debugging - and this same requirement is sufficient for lazy bundling to work. 114 | 115 | From user code's perspective the API for lazy bundling is `import()` + `React.lazy()`. These are APIs that already work in Metro (and in React web apps in general) so they do not need to be taught, but they are probably not used very often in existing React Native code (since they do not perform any form of bundle splitting by default). 116 | 117 | To get the most benefit out of lazy bundling, developers will want to use a navigation library that uses `import()` as the mechanism for lazy-loading route components. We can work with leading libraries like React Navigation and Expo Router to move the ecosystem in this direction without requiring changes to user code. 118 | 119 | Optionally, authors of navigation libraries may find it useful to ship AST transformations (Babel plugins) that inject `import()` calls at *all* route boundaries in development, regardless of whether the associated screen is intended to be lazy-loaded in production. This would provide a consistent set of split points and opt users of those libraries into a more scalable developer experience. 120 | 121 | ## Unresolved questions 122 | 123 | * User-facing naming: Are we happy with "lazy bundling" as the name for this feature? 124 | * APIs: Are we happy with `lazy=true` and `__loadBundleAsync` as the names for the new integration points between React Native and Metro? 125 | 126 | ## Acknowledgements 127 | 128 | The [initial version of lazy bundling in Metro](https://github.com/facebook/metro/commit/72329d02f2513eec024c42aa777bd445f573a968) was implemented at Meta by @cpojer. 129 | -------------------------------------------------------------------------------- /proposals/0641-decoupling-flipper-from-react-native-core.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Decoupling Flipper from React Native core 3 | author: 4 | - Alex Hunt 5 | - Nicola Corti 6 | - Aleksandar Andelkovic 7 | date: 2023-05-10 8 | --- 9 | 10 | # RFC0641: Decoupling Flipper from React Native core 11 | 12 | ## Summary 13 | 14 | We are planning to update the React Native app template to no longer use Flipper by default, and replace Flipper's JS debugging experience with an equivalent one-click debugging flow. This intends to simplify and improve the debugging and upgrade experiences for React Native developers. 15 | 16 | It is important to emphasise that Flipper as a product will remain available; only its integration with React Native will no longer be enabled out-of-the-box. We aim to provide a transition process for those who choose to maintain their own integration with Flipper, by externalising this as a separate package. 17 | 18 | We encourage React Native contributors to review this document thoroughly and to share your thoughts, ideas, and concerns. 19 | 20 | ## Motivation 21 | 22 | The React team has invested considerable time into understanding the pain points React Native developers are experiencing when developing their applications. Through this research, the top issue highlighted by our users and core contributors was the debugging experience, particularly Flipper ↔ React Native debugging. 23 | 24 | Feedback focused on four main areas: 25 | 26 | - Instability of the debugging experience with Flipper, frequent crashes, and difficulty performing even core workflows such as initial installation / connection to the host application. 27 | - The performance of the Flipper debugging experience and its user interface responsiveness was subpar compared to all other tools in the RN developer toolchain. 28 | - Flipper had been historically slow in addressing issues needed for the Flipper experience in React Native. 29 | - Flipper adds a number of transitive dependencies on both Android & iOS which is making build times longer and adds complexity to the release process. 30 | 31 | The React Native and Flipper teams spent time at the beginning of 2023 trying to find a way to address these issues and fund this work. However, it quickly became clear that the capacity of the Flipper team is prohibitive to them taking on an active role in addressing issues in React Native for Flipper. 32 | 33 | After careful analysis and to provide our users with the best developer experience, the React team has put together this proposal to decouple Flipper from React Native and deliver to the community a simple debugging solution relying on industry-standard protocols and tooling (which we can build upon further in future). 34 | 35 | The React team is fully aware that a number of our partners are invested in Flipper, and we will be working with the community to find a model that will allow a willing partner or larger ecosystem to take ownership of Flipper for React Native. 36 | 37 | ## Goals 38 | 39 | - **Community feedback**: Validate that we have covered the main React Native use cases of Flipper in this proposal. 40 | - **Decouple from Flipper**: Remove the built-in native Flipper integration from the template in React Native 0.74. 41 | - **One-click Hermes debug**: Ship a new default JavaScript debugging experience under Hermes by directly launching from the Dev Menu into Chrome DevTools. 42 | - **[Stretch] Docs improvements**: Expand our docs for native debugging to recommend alternative tools for native Flipper plugins (i.e. guidance for using Android Studio and Xcode Instruments). 43 | 44 | ## Detailed design 45 | 46 | ### Removal of native Flipper integration from the template 47 | 48 | The native integration code for Flipper currently takes up a significant effort out of our release process and general maintenance of React Native. 49 | 50 | As part of this proposal we will announce the deprecation of first-party support for Flipper in 0.73 and **no longer install Flipper** for newly created apps starting from 0.74 — removing all Flipper related code from the new app template. 51 | 52 | Here are some alternatives we're evaluating on how to handle the Flipper integration. 53 | 54 | #### 1. Create a separate library and look for a maintainer 55 | 56 | Our preferred alternative is to create a `@react-native-community/flipper-integration` library that will encapsulate and handle the Flipper integration for our users. [Flipper configuration files](https://github.com/facebook/react-native/blob/main/packages/react-native/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.kt) from the template should be moved there. 57 | 58 | This library should ideally be agnostic of both the React Native version and the Flipper version, so we foresee a low maintenance cost. 59 | 60 | **If you're interested in maintaining this library, please let us know.** 61 | 62 | #### 2. Create a module inside React Native to encapsulate the integration code 63 | 64 | Should we be unable to find a maintainer, we could encapsulate all the template logic (i.e. [files in user space](https://github.com/facebook/react-native/blob/main/packages/react-native/template/android/app/src/debug/java/com/helloworld/ReactNativeFlipper.kt)) into a separate module inside the React Native repository. For instance for Android, the library would live inside `packages/react-native/ReactAndroid/flipper/` or `packages/react-native-flipper-android/`. 65 | 66 | This package would still be published as part of the React Native release workflow, but will **not** be used by default by the app template. Users will be able to enable it with a one-line configuration if needed (or via autolinking). 67 | 68 | #### 3. Drop entirely and refer users to official Flipper documentation 69 | 70 | As a last resort, we can point users to the documentation of the Flipper website (which should be reviewed) and would replicate the current template setup: 71 | https://fbflipper.com/docs/getting-started/react-native-android/ 72 | https://fbflipper.com/docs/getting-started/react-native-ios/ 73 | 74 | ### New "Open Debugger" flow: One-click Hermes debug 75 | 76 | To replace the current Flipper-based "Open Debugger" flow in the Dev Menu (Hermes only), we will introduce a minimal one-click flow that connects the Hermes debugger endpoint with a local Chrome (or Microsoft Edge) DevTools instance. This is similar to the old way we allowed debugging React Native apps, but will now work with Hermes, connecting directly to the device to debug your app. 77 | 78 | This will become the new default experience for direct JS debugging in apps using Hermes, and will remove the requirement of having Flipper set up on a developer machine to reach this core debugging capability. 79 | 80 | We plan to implement this experience in React Native CLI via a new `/open-debugger` endpoint. This replaces the current "Open Debugger" flow (which attempts to open Flipper via a `flipper://` URL scheme and fails otherwise). 81 | 82 | ![Sketch architecture for one-click Hermes debug](./assets/0641-one-click-hermes-debug.png) 83 | 84 | Since this new debugging flow fills a gap when users do not have Flipper installed, we aim to add this logic against the "Open Debugger" button by default — replacing previous `flipper://` URL actions in the Dev Menu. 85 | 86 | ### Replacing "Open React DevTools" 87 | 88 | We will also aim to replace the “Open React DevTools” flow in the Dev Menu, via a similar endpoint in React Native CLI that opens the standalone React DevTools app (or in a browser window). This is less of a priority than the above, as today we have a [standalone React DevTools connection flow](https://reactnative.dev/docs/next/react-devtools) that works without this button. 89 | 90 | ### Documenting alternative existing native debugging tools 91 | 92 | We understand that Chrome DevTools alone won't replace the functionality of the current suite of Flipper native debugging plugins, and will be supporting this by improving our docs on debugging with first-party native debugging tools. 93 | 94 | - [Crash Reporter](https://fbflipper.com/docs/features/plugins/crash-reporter/) — Android Studio/Logcat and Xcode 95 | - [Databases Plugin](https://fbflipper.com/docs/features/plugins/databases/) — [Android Studio](https://developer.android.com/studio/inspect/database) 96 | - [Network Plugin](https://fbflipper.com/docs/features/plugins/network/) — [Charles Proxy](https://www.charlesproxy.com/documentation/configuration/browser-and-system-configuration/), [mitmproxy](https://medium.com/@rotxed/how-to-debug-http-s-traffic-on-android-7fbe5d2a34#.hnhanhyoz) (Android), [Fiddler](https://www.telerik.com/fiddler), [Chucker](https://github.com/ChuckerTeam/chucker) 97 | - [Shared Preferences Viewer](https://fbflipper.com/docs/features/plugins/preferences/) — TBC 98 | - [UI Debugger Plugin](https://fbflipper.com/docs/features/plugins/ui-debugger/) — Android Studio and Xcode 99 | 100 | ### Note: This is not the end state for React Native debugging 101 | 102 | We acknowledge that the "Open Debugger" and "Open React DevTools" flows previously launched Flipper, which offered the promise of a cohesive, easy to teach, and extensible experience for users. From that perspective, these proposed changes aren’t strictly better. 103 | 104 | We see this — decoupling from Flipper to simplify React Native core and reset the baseline reliability of the debugging experience — as one of the first steps in our journey to up-level the debugging experience for React Native developers. 105 | 106 | The React Native and Hermes teams are committed to continue our investments in this area. We hope to ship improvements to CDP support for Hermes and enhancements to the debugging experience by establishing a stable foundation for seamless communication between the application at runtime and debugging clients (such as Chrome DevTools Frontend). 107 | 108 | ## Adoption strategy 109 | 110 | We aim to complete this work within the next two React Native development cycles. This is motivated by unburdening the React Native release crew from Flipper-introduced overheads, balanced with giving developers and library maintainers time to adopt and migrate. 111 | 112 | Additionally, this gives us time to ship further debugging improvements on top of the Chrome DevTools flow we will deliver in 0.73. 113 | 114 | ### Target release for deprecation: React Native 0.73 (Q3 2023) 115 | 116 | - The native Flipper integration remains in the template and enabled by default. 117 | - The new Chrome DevTools-based debugging flow is shipped and replaces the "Open Debugger" and "Open React DevTools" actions in the Dev Menu. Flipper must be opened separately to connect to a running React Native app. 118 | - Flipper will no longer be recommended as the default debugging tool for React Native — except for compatibility with today's Flipper plugins. 119 | 120 | ### Target release for removal: React Native 0.74 (Q4 2023/early 2024) 121 | 122 | - The native Flipper integration is no longer present in the template. Developers must follow manual setup steps from the Flipper docs to install Flipper in new React Native projects. 123 | - If we've found an owner to maintain the React Native Flipper integration, this may be a simpler case of adding and linking a `@react-native-community/flipper-integration` library. 124 | 125 | ## How we teach this 126 | 127 | ### General communication 128 | 129 | > It is important to emphasise that Flipper as a product will remain available; only its integration with React Native will no longer be supported out-of-the-box. 130 | 131 | - Highlight the availability of the new one-click Hermes debug experience. 132 | - Communicate that Flipper is no longer the default recommended tool. 133 | - Highlight the ability to re-integrate Flipper via new external library. 134 | 135 | ### User guide for re-integrating Flipper 136 | 137 | - We'd like a partner to own this. 138 | - Can live on the React Native website or in the README of the separate repo. 139 | - Document the availability of this prominently in the React Native changelog. 140 | -------------------------------------------------------------------------------- /proposals/0684-adding-e2e-in-core.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introducing E2E testing in React Native core 3 | author: 4 | - Lorenzo Sciandra 5 | - Nicola Corti 6 | - Riccardo Cipolleschi 7 | - Mateusz Ulańczyk 8 | - Adrian Orszulik 9 | - Mateusz Michalec 10 | - Elżbieta Berger 11 | - Michał Pierzchała 12 | - Szymon Rybczak 13 | date: 2023-07-06 14 | --- 15 | 16 | # RFC0684: Introducing E2E testing in React Native core 17 | 18 | ## Summary 19 | 20 | Testing is how we validate that the code is good, and ensure that what we build our products on top of is solid and our customers are happy. 21 | 22 | For the longest time, in React Native core this validation has been done in a few ways: 23 | 24 | - via Meta using the source code in their own products first 25 | - via internal testing with custom tooling in the Meta monorepo 26 | - via (mostly) unit testing on the CircleCI GitHub `react-native` repo 27 | - via local testing by the release crew ahead of generating new releases 28 | - via "pre-stable" releases (AKA Release Candidates and nightlies) that members from the community could use to test and report back 29 | 30 | There is a great opportunity for improvement here, by introducing End-to-End (E2E) testing in the CircleCI GitHub `react-native` repository to introduce one more level of validation that aims to replace the need for (at least) the local testing from the release crew. By adding tooling that spins up the RNTester app in the codebase, and "black box" (the RNTester app is not aware that the agent using it is not a human) testing it, we can trust that the code is more solid. 31 | 32 | This will make the codebase more stable, surface issues rapidly to the commit authors, and reduce the workload for the release crew. 33 | 34 | ## Basic example 35 | 36 | On a basic level, the idea is to have fully automated end-to-end testing running on CircleCI on `react-native`'s to flag if any code change is inadvertently introducing a regression of some form. 37 | 38 | The code and tests to do so will live in a new dedicated monorepo package, `packages/rn-tester-e2e` and rely on the existing `RNTester` test app. 39 | 40 | The tooling combination selected for this is composed of [Appium](https://appium.io/) and [WebDriverIO](https://webdriver.io/) and [Jest](https://jestjs.io/). 41 | 42 | ## Motivation 43 | 44 | The main "why" has already been explained above: introducing more solid automation to thoroughly verify that code changes don't introduce regressions. 45 | 46 | This will lead to removing the need for the release crew to do manual local testing to validate the code before a release, which by being an human operation can lead to flukes. Additionally, this means that the time-to-release will get shorter because the release crew won't need to run those tests. 47 | 48 | Another explanation necessary is the stack decision: the reason is that it's the combination that gets the closest to the specific requirements of React Native's unique structure. We needed to fulfil these needs: 49 | 50 | - had to be "vanilla Jest" based 51 | - in order to very closely match the internal Meta monorepo tooling used by the engineers, and in doing so lower the barrier to entry to add tests for this set too 52 | - had to not touch RNTester code (pure black box testing) 53 | - needed to support device farm 54 | - while in a first phase the testing will run on CI on emulator/simulators, we are aware of the inherit flakyness so we want to start using a device farm relatively soon during the work on this effort 55 | - easy to extend to out of tree platforms (ex. Windows, macOS) 56 | - RNWindows already uses [a very similar stack](https://github.com/microsoft/react-native-windows/blob/main/docs/e2e-testing.md). 57 | 58 | With that specific combination of needs, Appium+WBIO+Jest came out as the only viable option. 59 | 60 | ## Detailed design 61 | 62 | As already mentioned, the core stack involved is composed of [Appium](https://appium.io/) and [WebDriverIO](https://webdriver.io/) and [Jest](https://jestjs.io/). 63 | 64 | The dedicated code configuring the tooling and the tests will be in its own private package in `packages/rn-tester-e2e`. The app used for testing is RNTester (in `packages/rn-tester`), an app already present in the codebase which contains code for every component and API with sample implementations. 65 | 66 | In it, the `tests` folder is where the tests and referencing files all live. The substructure is as follows: 67 | 68 | rn-tester-e2e 69 | └──tests 70 | ├── screens 71 | ├── specs 72 | └── helpers 73 | 74 | - `screens` -> in this folder, you will find `*.screen.js` files, where each file represents a navigation screen for RNTester. So there are 3 root ones (`apis`, `bookmarks`, `components`) and then for subscreens, there's a folder with the same name. Each of these files provide an easy way to define all elements present in said screen, so that they can be used for tests. 75 | - for each element of a given screen there will be a platform-specific reference in the form of 76 | 77 | ```js 78 | btnSubmitElement: Utils.platformSelect({ 79 | ios: iOSLabel('Press to submit your application!'), 80 | android: androidWidget('Button', 'resource-id', 'button_default_styling'), 81 | }), 82 | ``` 83 | 84 | we did, during early investigations, attempt to figure out more streamlined and universal solutions, such as relying on accessibility labels like `testID`s, but it created inconsistent scenarios nor every element on screen always had a `testID` available. 85 | 86 | *sidenote: `iOSLabel` and `androidWidget` are utility functions created while working on [the first PR](https://github.com/facebook/react-native/pull/36267). More utility functions to further simply writing tests can be added as work progresses.* 87 | 88 | - `specs` -> this folder follows a similar 1:1 mapping to the RNTester screens, but for the tests: for each screen (or subscreen) there's a dedicated `*.test.js` file (such as `buttonComponentScreen.test.js`). Ideally, in this file the Jest tests are standard, leveraging the `*.screen.js` counterpart for the details of defining how Appium/WDIO can reach those elements on screen. 89 | - `helpers` -> where utility code, such as methods for checking element existence, clicking interaction, etc. will live 90 | 91 | These tests will be ran on the existing CircleCI infrastructure already set up for `react-native` on GitHub, so we will need to add two new dedicated jobs for E2E testing, `test_e2e_ios` and `test_e2e_android` and add them to the existing workflows that run on every commit. 92 | 93 | ## Drawbacks 94 | 95 | - CI will get slower because we are introducing new jobs to the pipelines. 96 | - during the first iteration, only on CI, tests might be flaky. 97 | - it will take a lot of time before the whole RNTester surface area will be covered with E2E tests. 98 | 99 | ## Alternatives 100 | 101 | There are not many tools in the end to end space when it comes to React Native; of the known alternatives, neither of the following fitted our needs: 102 | 103 | - [Detox by Wix](https://github.com/wix/Detox) 104 | - greybox testing 105 | - no support for device farms 106 | - no desktop platforms support 107 | - [Maestro](https://github.com/mobile-dev-inc/maestro) 108 | - yaml based testing 109 | - no desktop platforms support 110 | - no support for device farms (unclear?) 111 | 112 | > ⚠️ This does not mean, obviously, that these are not good tools and you should not use them in your projects! But that simply for our specific requirements, they weren't viable options. 113 | 114 | ## Adoption strategy 115 | 116 | This proposal doesn't directly affect consumers of React Native, only contributors and commit authors. 117 | 118 | The current roadmap is as follows: 119 | 120 | - a first PR, introducing the core infrastructure for E2E with documentation and CI integration, is prepared and merged 121 | - This is already in the works, check out [the dedicated PR](https://github.com/facebook/react-native/pull/36267) 122 | - after that one is merged, an umbrella issue is created (similar to the one for [the codegen](https://github.com/facebook/react-native/issues/34872), or [Kotlin](https://github.com/facebook/react-native/issues/37708)) to ask the community to contribute by adding tests in order to cover the whole RNTester surface area. 123 | - while the test get added and the coverage grows, there are two stretch goals that will be pursued: 124 | - adding a device farm as testing environment so to replace the need for using emulators and simulators on CI 125 | - expand the toolset to cover also for screenshot testing 126 | - this is current still being investigated (might end up having its own RFC), some tooling that was looked at was [`jest-image-snapshot`](https://github.com/americanexpress/jest-image-snapshot) 127 | 128 | ## How we teach this 129 | 130 | Because this proposal doesn't directly affect consumers of React Native, the need for "teaching content" is scoped to people who wants to learn more about this infrastructure is set up and they want to contribute with more tests. 131 | 132 | The first place where this type of documentation will be added is the readme of the dedicated new folder, `packages/rn-tester-e2e/README.md` *(you can already check out a draft of it [in the first PR](https://github.com/mateuszm22/react-native/blob/k+m/new-rn-tester-E2E/packages/rn-tester-e2e/README.md) already in the works)*. In this file, there are going to be information on how the setup works, how to test it locally and how to add new tests. 133 | 134 | Building on top of that, an umbrella issue will be created to coordinate and provide actionable examples for how to add new tests. In it, a streamlined explanation will be provided that will then reference back to the dedicated `packages/rn-tester-e2e/README.md`. 135 | 136 | And, of course, we can also point people to this RFC for more context/historical details. 137 | 138 | -------------------------------------------------------------------------------- /proposals/0744-well-defined-event-loop.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Well-defined event loop processing model 3 | author: Rubén Norte 4 | date: 2023-12-11 5 | updated: 2023-12-11 6 | --- 7 | 8 | # RFC0744: Well-defined event loop processing model 9 | 10 | ## Summary 11 | 12 | This is a proposal to formalize the steps that React Native follows to perform tasks on the JavaScript thread, and how that work is synchronized with rendering work in the host platform. 13 | 14 | The main goals are: 15 | * Make the behavior of the framework more predictable, to help developers build more reliable and performant apps. 16 | * Increase the alignment with Web specifications, to simplify the adoption of Web APIs in React Native. 17 | * [Secondary] Provide a solid foundation for general performance optimizations relying on better scheduling or sequencing. 18 | 19 | The scope of this proposal is restricted to: 20 | * Apps using the new React Native architecture. 21 | * Existing features and APIs in React Native. Even though the Web defines steps for APIs that we want to eventually adopt in React Native (like `ResizeObserver`), those are out of the scope of this proposal and will be considered as a future extension. 22 | 23 | This proposal is heavily inspired by the [event loop processing model defined in the HTML specification](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model), bringing only the concepts that are useful for React Native. 24 | 25 | **_NOTE: When we talk about how React Native works in this document we are only referring to the new architecture._** 26 | 27 | ## Basic example 28 | 29 | This proposal does not introduce new APIs but changes the behavior of some of the existing ones. 30 | 31 | The most important changes are: 32 | * Refs, layout effects and passive **effects** in React components would have **access to layout information synchronously** and would **block paint** until completed (except on passive effects for async updates). At the moment, React Native executes effects and computes layout in parallel, so users have no guarantees about their sequencing. 33 | * Microtasks would be properly supported, instead of being polyfilled using timers. They would also block paint as they do on the Web. 34 | 35 | Examples: 36 | * Synchronous access to layout information: 37 | ```javascript 38 | function MyComponent(props) { 39 | const ref = useRef(); 40 | 41 | // Via effects 42 | useLayoutEffect(() => { 43 | // Using the new DOM APIs 44 | console.log('Client rectangle is', ref.current.getBoundingClientRect()); 45 | 46 | // Using the legacy measurement APIs 47 | let rect; 48 | ref.current.measureInWindow((x, y, width, height) => { 49 | rect = new DOMRect(x, y, width, height); 50 | }); 51 | console.log('Client rectangle is', rect); 52 | }, []); 53 | 54 | return ( 55 | <> 56 | 57 | { 59 | // Via ref callback 60 | console.log('Client rectangle is', element.getBoundingClientRect()); 61 | }} 62 | /> 63 | 64 | ); 65 | } 66 | ``` 67 | * Atomic UI updates: 68 | ```javascript 69 | function MyComponent(props) { 70 | const [width, setWidth] = useState(0); 71 | 72 | useLayoutEffect(() => { 73 | // We would also wait for this update before painting to the screen, 74 | // Instead of having multiple updates causing flicker. 75 | setWidth(ref.getBoundingClientRect().width); 76 | }, []); 77 | 78 | return ( 79 | <> 80 | 81 | 82 | 83 | ); 84 | } 85 | ``` 86 | 87 | ## Motivation 88 | 89 | The main motivation for this proposal is to **fix a series of problems** in React Native that prevent it from **implementing the React programming model correctly**. This programming model defines a series of abstractions and assumptions that developers can rely on to build applications, independently of the platforms they are targeting. If you look at the [React documentation](https://react.dev/reference/react), everything under the `react` package (not in `react-dom`) should work the same way across platforms. 90 | 91 | That’s not the case for hooks like `useLayoutEffect`. From [its documentation](https://react.dev/reference/react/useLayoutEffect): 92 | * _useLayoutEffect is a version of useEffect that fires before the browser repaints the screen_ 93 | * Forgiving their mention to the browser, in React Native `useLayoutEffect` is not guaranteed to run before repainting the screen. 94 | * _Call useLayoutEffect to perform the layout measurements before the browser repaints the screen_ 95 | * In React Native, layout effects can fire before layout information has been computed, so accessing layout information can provide stale or incorrect data. 96 | * The code inside useLayoutEffect and all state updates scheduled from it block the browser from repainting the screen 97 | * Again, this is not the case in React Native. The tree for which we are processing effects is mounted in parallel in the host platform. 98 | 99 | The main goal of this hook is to allow multi-pass renders without causing UI thrash, and this goal is not accomplished in React Native with its current semantics. 100 | 101 | Another important motivation for this proposal is to **increase alignment with the Web platform**. The Web provides capabilities that are often necessary to build high quality applications. With this proposal, bringing APIs related to rendering with the right semantics, like `IntersectionObserver` and `ResizeObserver`, becomes easier, which also simplifies sharing code across these platforms. 102 | 103 | For example, `ResizeObserver` callbacks run after tasks and microtasks have been executed, but before the browser repaints the screen. If we want to be able to bring code from the Web into React Native using this API, we need to follow the same semantics, or otherwise users could find behavior differences or bugs. 104 | 105 | Finally, by having a well defined processing model for the event loop, we can rely on the guarantees it provides to **implement optimizations**, both in applications and in the framework itself. For example, we could move layout events (via `onLayout`) to be dispatched as microtasks, so we can batch them with the original changes that triggered them, reducing UI thrash and potentially eliminating mounting instructions from React to the host platform. We can also rely on this processing model to efficiently implement events that are processed synchronously from the main thread. 106 | 107 | ## Detailed design 108 | 109 | ### Conceptual model 110 | 111 | #### Current conceptual model 112 | 113 | The most important change that this proposal would introduce is the order of execution of `useLayoutEffect`, `useEffect` and mounting the changes in the host platform (what would be considered “repaint” in Web browser terms). 114 | 115 | At the moment, after every commit in React, this happens **in parallel**: 116 | * **React** propagates refs, mounts effects (executes `useLayoutEffect` callbacks and lifecycle methods like `componentDidMount` and `componentDidUpdate`) and mounts passive effects (synchronously or in a microtask, depending on the priority of the current rendering work), in that order. 117 | * **The React Native renderer** schedules a task in a background thread to commit the new UI tree and compute its layout. When that is completed, the host platform is notified to mount the changes in the main thread. 118 | 119 | ![Diagram showing how React Native processes updates coming from React (in asynchronous events)](assets/0744-fabric-current-async-update-embedded-diagram.png) 120 | 121 | This has 2 important consequences that make React Native behave differently than React DOM: 122 | 1. Layout information might not be available when executing layout effects, as there are no synchronization mechanisms for it. 123 | 2. Paint is not blocked on effects in React, so intermediate UI states could be flushed to the host platform and shown to the user. 124 | 125 | In this proposal, those differences would be removed and React Native would behave the same way as React DOM, while preserving the advantages of its threading model. 126 | 127 | #### New conceptual model 128 | 129 | The new model would be **more aligned with [the model on the Web](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model)** (from which we will borrow some concepts and steps), while **still benefiting from the React Native threading model**. 130 | 131 | This would introduce an event loop processing model for React Native, which will precisely describe the sequencing between JavaScript execution and rendering. 132 | 133 | This event loop would continuously go through these steps: 134 | 1. Select the next task to execute among all tasks waiting for execution. 135 | 2. Execute the selected task. 136 | 3. Execute **all** scheduled microtasks. 137 | 4. Update the rendering. 138 | 139 | ![Diagram showing how this proposal changes how React Native processes updates coming from React (in asynchronous events)](assets/0744-fabric-event-loop-async-update-embedded-diagram.png) 140 | 141 | One of the key benefits of this model is that each **event loop iteration represents an atomic UI update**. This helps reason about whether work scheduled within a specific task should be rendered together or not. If it is a step in the same task, scheduled as a microtask or one of the specific sub-steps in updating the rendering, then it will be atomic. Otherwise, if it was scheduled as a separate task (e.g.: using timers, native callbacks, etc.) it would constitute a separate UI update. 142 | 143 | ##### Detailed steps 144 | 145 | ###### 1. Task selection 146 | 147 | On the Web, task selection is an implementation detail left to browsers to decide. 148 | 149 | In React Native, there is already a Runtime Scheduler that supports the execution of tasks with priorities, so we can rely on it for task selection. The criteria it is currently using is: 150 | 1. If there are expired tasks, select expired tasks in the order in which they expired. 151 | 2. Otherwise, select tasks by priority, in the order in which they were scheduled. 152 | 153 | The Web spec defines the concept of task queues as a mechanism to ensure that certain types of tasks execute in a specific order (e.g.: events). We already have the concept of event queues in React Native that serve the same purpose and we can continue using it after this. 154 | 155 | 156 | ###### 2. Task execution 157 | 158 | The way we execute tasks would not change after this change. It would continue being the execution of a C++ function that accesses the JS runtime to perform its logic. 159 | 160 | ###### 3. Microtask execution 161 | 162 | In this step we would drain the microtask queue, executing all the microtasks in order. A microtask can schedule additional microtasks, so incorrect product logic could lead to an infinite loop here. This is expected and it is the same behavior it has on the Web. 163 | 164 | ###### 4. Update the rendering 165 | 166 | The last step is to check if the previous work produced new commits in Fabric. If that was the case, we would notify the host platform that it should apply the necessary mutations to reach that state. 167 | 168 | In the future, we could extend this step to do more of the work that browsers do. For example, we could run resize observations here, or update animations and run animation frame callbacks. 169 | 170 | ##### Synchronous execution, events and rendering 171 | 172 | Formalizing this event loop that synchronizes with rendering also allows us to efficiently implement synchronous events. 173 | 174 | The main problem to implement synchronous events with the existing model is that we do not know which tasks should be processed together to be rendered atomically. This means that we could end up executing too little JavaScript code in the UI thread, leading to an unfinished UI state, or too much, leading to blocking the UI thread for longer than necessary, negatively impacting responsiveness. 175 | 176 | The benefit of this model is that it defines what is the unit of work that leads to a full UI update, which means we know exactly how much code to execute in the UI thread. In this case, we would only go through a single iteration of the event loop, which would provide those guarantees. 177 | 178 | ![Diagram showing how this proposal would allow React Native to process synchronous events](assets/0744-fabric-event-loop-sync-update-embedded-diagram.png) 179 | 180 | ### Implementation 181 | 182 | #### Event Loop 183 | 184 | To preserve the semantics of the event loop defined here, we need to make sure all JS tasks execute through it. Both in the old and in the new architecture, all tasks are scheduled through a `RuntimeScheduler` instance, which implements a priority queue on top of the message queue exposed by `RuntimeExecutor`. We could build our event loop processing logic inside that abstraction. 185 | 186 | The current `RuntimeScheduler` implementation has a few limitations that we should address as part of this effort (e.g.: not being able to schedule work outside of the JS thread with custom priorities or avoiding asking the current task to yield). 187 | 188 | After that, we need to extend the implementation to implement the steps in the loop: 189 | * To add support for microtasks, we would need to execute them after executing the main work of the task. Additional work is required in the JS runtime to enable native microtasks (exposing the `queueMicrotask` function and relying on them for promises) and in React (enabling microtasks for scheduling/batching). 190 | * To prevent React commits to be mounted on the host platform before the “Update the rendering” step in the loop, we would need to avoid notifying the [SchedulerDelegate](https://github.com/facebook/react-native/blob/c95b2d97281b32cf00490be8d8f9358acfa000c1/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h#L28C35-L28C35) about these commits and wait for this step to notify all pending changes. In RuntimeScheduler, we could expose a new API to queue these notifications (e.g.: scheduleRenderingUpdate) from the React Native [Scheduler](https://github.com/facebook/react-native/blob/c95b2d97281b32cf00490be8d8f9358acfa000c1/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp#L307). 191 | 192 | #### React renderer updates 193 | 194 | The React reconciler uses microtasks for batching updates and to schedule paint-blocking work, if they are available. The React Native renderers (Fabric) [is configured as not having support for microtasks](https://github.com/facebook/react/blob/bb1d8d166799eb97892be6c7826179270ba283d0/packages/react-native-renderer/src/ReactFiberConfigFabric.js#L125), so the reconciler falls back to [using a scheduler function to schedule tasks with immediate priority](https://github.com/facebook/react/blob/bb1d8d166799eb97892be6c7826179270ba283d0/packages/react-reconciler/src/ReactFiberRootScheduler.js#L491). We would need to add a feature flag in React to enable the use of microtasks in Fabric. 195 | 196 | #### Background executor 197 | 198 | The new React Native renderer (Fabric) provides an option to commit React trees in a background thread, doing layout, mount, etc. asynchronously, outside of the JavaScript thread. This option was provided to offset some of the performance regressions that Fabric introduced due to the increased amount of work that it performs in the JavaScript thread. Unfortunately, it is also the main reason why `useLayoutEffect` does not have the correct semantics in React Native. As part of this proposal, that option and the background executor would be removed. 199 | 200 | ## Drawbacks 201 | 202 | This would introduce changes in the semantics of existing applications. We expect these to be transparent for end users in most cases, but applications relying on the ordering or timing of specific events could be affected by this. See the _Adoption strategy_ section for more details. 203 | 204 | ## Alternatives 205 | 206 | None considered that would accomplish the same goals. We define a custom processing model for React Native, but that would not achieve the goal of aligning with Web standards. 207 | 208 | ## Adoption strategy 209 | 210 | Ideally we would **ship this as part of the new React Native architecture**. We expect users to thoroughly test their applications when migrating to the new architecture to make sure everything works as expected. If we shipped these changes as part of the new architecture, users would not need to do another round of testing for this specific feature. This might increase the number of differences between the old architecture and the new one, but the cost of identifying and fixing potential problems at this point should be lower than doing it separately. 211 | 212 | If these changes are not ready by the time we are ready to roll out the new architecture, this could be rolled out gradually using a feature flag. We could introduce this flag in a minor version of React Native and make it the default in the following major version. 213 | 214 | ## How we teach this 215 | 216 | There is currently very little documentation about the current processing model in React Native. We have [some documentation about the new architecture](https://reactnative.dev/architecture/fabric-renderer), but it only covers the integration between React, React Native and the host platform at the React commit level, but it does not talk about how it coordinates with JavaScript execution. 217 | 218 | We could fill this void by referencing existing documentation for the event loop on the Web, and pointing out specific differences between the Web and React Native. For developers with a Web background, documentation might not even be necessary (as the actual behavior would align with their expectations). 219 | 220 | ## Unresolved questions 221 | 222 | * Add an example (code snippet and/or video) that shows how multi-pass updates look like before and after this proposal. 223 | * What are examples of behavior changes we could expect from this change? 224 | * We are currently testing these changes at Meta and we will be able to update this document as we learn from it. 225 | 226 | ## Future extensions 227 | 228 | * Implementing synchronous execution/**synchronous events**, leveraging the event loop to know how much code we need to execute in the main thread (a single iteration of the event loop). 229 | * Modifying **layout events** (`onLayout` in native components) to be dispatched **using microtasks** in the same task where the commits happen, instead of as separate tasks. This would improve performance (as we would reduce the frequency of diffing and the number of mounting instructions) and UX (as we’d paint the original commits and any work done in `onLayout` atomically. 230 | * We have been testing implementations of a subset of `IntersectionObserver` and `MutationObserver`. After this proposal is implemented, we could modify those implementations to bring them closer to the Web specification (e.g.: using microtasks for `MutationObserver` callbacks, computing intersections in the “Update the rendering” step, etc.). 231 | * Implementing spec-compliant versions of `requestAnimationFrame`, `requestIdleCallback`, Long Task API, Event Timing API, etc. 232 | * Implementing lazy layout computation, to bring some of the benefits of Background Executor with the semantics defined in this document. 233 | 234 | ## Changelog 235 | 236 | | Date | Author | Change | 237 | |---|---|---| 238 | | 2023-12-11 | [Rubén Norte](https://github.com/rubennorte) | Initial version published | 239 | -------------------------------------------------------------------------------- /proposals/0777-remove-legacy-element-inspector-features.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Removing the "Perf" and "Network" tabs from the in-app Element Inspector 3 | author: 4 | - Alex Hunt 5 | date: 2024-04-04 6 | --- 7 | 8 | # RFC0777: Removing the "Perf" and "Network" tabs from the in-app Element Inspector 9 | 10 | ## Summary 11 | 12 | This RFC identifies two sub-features of the in-app Element Inspector which we believe are **not worth reimplementing** under the New Architecture. 13 | 14 | **Proposed features to remove** 15 | 16 | These will not be available under the New Architecture. 17 | 18 | - Element Inspector > Perf 19 | - Element Inspector > Network 20 | 21 | **Proposed features to keep (no change)** 22 | 23 | - Element Inspector > Inspect 24 | - Element Inspector > Touchables 25 | 26 | ## Motivation 27 | 28 | As the React team focuses on the New Architecture and Debugging, we are reviewing the current development tooling we offer. 29 | 30 | The in-app Element Inspector is a longstanding development feature in React Native, which helps developers visually understand the element hierarchy in their app via tap interaction and through its React DevTools integration. However, its UI also houses some adjacent features which are unrelated to this purpose, are ambiguous with other built-in tools, and have been little-maintained. 31 | 32 | As we build out the New Architecture, we need to consider the usefulness of these features and the cost of adapting and maintaining these against the Bridgeless model. So, we are considering the removal of both the **Perf** and **Network** features under the Element Inspector overlay, under the New Architecture. 33 | 34 | - Under the current architecture: Leave these features in place. 35 | - Under the New Architecture: Do not reimplement these features, removing the "Perf" and "Network" buttons. 36 | 37 | ## Detailed design 38 | 39 | ### Legacy features to remove 40 | 41 | ![Screenshot showing the legacy Perf and Network panels in the Element Inspector overlay](../assets/element-inspector-legacy-panels.png) 42 | 43 | #### 1. Element Inspector > Perf 44 | 45 | Functionality: Textual logs of network requests with request duration. Non-interactive, no scrolling. 46 | 47 | A "Perf" tool here is ambiguous with the "Perf Monitor" feature we provide in the Dev Menu (which displays a standalone performance overlay), additionally motivating its removal. 48 | 49 | #### 2. Element Inspector > Network 50 | 51 | Functionality: A table view of HTTP requests made from the application. Non-interactive. 52 | 53 | ### Replacing these features 54 | 55 | The functionality and value of both of these tabs is limited, providing basic visibility into network events. We believe there is better tooling, both today and in our future Debugging plans, that encapsulate these offerings. 56 | 57 | - Replacement tooling (today): native network inspectors (e.g. Charles Proxy), Network panel (web), console logs. 58 | - Replacement tooling (future): Fully functional Network panel in Chrome DevTools (**available in Expo today**). 59 | 60 | ### Legacy features to keep (input wanted) 61 | 62 | We believe that the below tabs within the Element Inspector are a combination of more useful, relevant, and popular than the "Perf" or "Network" panels. 63 | 64 | - Element Inspector > Inspect 65 | - Element Inspector > Touchables 66 | 67 | There is some replacement tooling for these features, e.g. element highlighting from React DevTools, and native view inspection in Xcode/Android Studio. 68 | 69 | ## Adoption strategy 70 | 71 | None, remove these features for the New Architecture. 72 | 73 | ## How we teach this 74 | 75 | In a future release announcement that includes the full New Architecture by default, note this change. 76 | -------------------------------------------------------------------------------- /proposals/0836-lean-core-jsc.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Extract JSC (JavaScriptCore) from React Native Core 3 | author: 4 | - Kudo Chien 5 | date: 2024-11-28 6 | --- 7 | 8 | # RFC0836: Extract JSC (JavaScriptCore) from React Native Core 9 | 10 | ## Summary 11 | 12 | This RFC proposes a Lean Core effort to extract JSC (JavaScriptCore) from React Native's core. 13 | 14 | ## Proposed Changes and Timeline 15 | 16 | - **Version 0.78**: Remove the [`jsc-android` npm dependency](https://github.com/facebook/react-native/blob/2d337efc23c662143b3f39a6c994d80fec047054/packages/react-native/package.json#L132) from React Native and instead download the artifact from Maven Central. When using Hermes, downloading the unused npm dependency is unnecessary and removing it saves about 32 MB of uncompressed build time size. 17 | - **Version 0.79**: Introduce the community [`@react-native-community/javascriptcore`](https://github.com/react-native-community/javascriptcore) package, allowing developers to begin migrating from core JSC to the community-maintained version. Using the core JSC will trigger a build-time warning about its upcoming removal: 18 | - React Native core will reduce its [testing support](https://github.com/reactwg/react-native-releases/blob/main/docs/guide-release-testing.md#dimensions-to-test) for JSC. 19 | - The community JSC package will include basic end-to-end tests. 20 | - **Version 0.80**: The `@react-native-community/javascriptcore` package will offer a newer JSC version on Android that may support modern JavaScript language features, such as [`BigInt`](https://github.com/react-native-community/jsc-android-buildscripts/pull/169). In this updated `jsc-android`, only the [`Intl` variant](https://github.com/react-native-community/jsc-android-buildscripts/blob/9c61fece4753902a2cd6d29dfa46b7b521f0c821/README.md#international-variant) will be provided because newer JavaScriptCore versions do not support disabling `Intl` The core JSC remains available in this version with a build-time warning: 21 | - Update documentation at https://reactnative.dev/docs/hermes to recommend the community JSC. 22 | - **Version 0.81 or 0.82**: Completely remove JSC from the core: 23 | - Eliminate `JSCRuntime` code and drop support for `useThirdPartyJSC`. 24 | 25 | ## Motivation 26 | 27 | Since Hermes has become the dominant JavaScript engine in the React Native ecosystem, it is inefficient to include unused JavaScriptCore code and binaries in the core. By extracting JavaScriptCore to a separate, third-party maintained library, we can streamline the core and reduce unnecessary bloat. 28 | 29 | ## Adoption strategy 30 | 31 | We will offer a drop-in replacement with the [`@react-native-community/javascriptcore`](https://github.com/react-native-community/javascriptcore) package while maintaining JSC support in the core for two additional React Native releases to ensure a smooth transition. 32 | 33 | > [!NOTE] 34 | > The community JSC will only support New Architecture mode. 35 | 36 | ### Mixing `JSCRuntime` from core and third-party 37 | 38 | Originally, the `hermesEnabled` flag in Android's **gradle.properties** and `hermes_enabled` flag in iOS's **Podfile** served two purposes: creating the Hermes bytecode bundle and selecting JSCRuntime over HermesRuntime. During the transition period, we will introduce a `useThirdPartyJSC` flag in **gradle.properties** and `ENV['USE_THIRD_PARTY_JSC']` in CocoaPods. When `useThirdPartyJSC` is enabled, React Native will not link the core `JSCRuntime`. 39 | 40 | ### Setup guide for `@react-native-community/javascriptcore` 41 | 42 | Refer to the [README from `@react-native-community/javascriptcore for setup instructions](https://github.com/react-native-community/javascriptcore/blob/main/README.md). 43 | 44 | ## How we teach this 45 | 46 | - We will announce the upcoming changes in the version 0.79 release notes and provide guidance for developers on migrating to the new `@react-native-community/javascriptcore` package. 47 | - A build-time warning in React Native will notify users about the upcoming lean core changes regarding JSC. 48 | -------------------------------------------------------------------------------- /proposals/0894-deprecate-subpath-imports.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Removing deep imports from react-native 3 | author: 4 | - Alex Hunt 5 | date: 2024-04-04 6 | --- 7 | 8 | # RFC0894: Removing deep imports from `react-native` 9 | 10 | ## Summary 11 | 12 | In this RFC, we propose removing **subpath imports** (or "**deep imports**") from React Native's JavaScript API. 13 | 14 | These imports, such as the below, allow direct access to internal modules. While historically supported, we plan to phase out subpath imports to reduce our API surface area. 15 | 16 | ```ts 17 | // Before - subpath imports allowed 18 | import {Alert, AlertType} from 'react-native/Libraries/Alert/Alert'; 19 | 20 | // After - must import from 'react-native' 21 | import {Alert, AlertType} from 'react-native'; 22 | ``` 23 | 24 | Doing this will: 25 | 26 | - Define a clear public API contract for `react-native` that minimises future breaking changes. 27 | - Improve maintainability for React Native and its ecosystem. 28 | 29 | #### Planned sequencing 30 | 31 | - React Native 0.80: Deprecation of subpath imports, introduce runtime warnings. 32 | - React Native 0.82 (or later): Removal of subpath imports via `"exports"` and the Strict TypeScript API. 33 | 34 | Between deprecation and removal, we will hold an API consultation period over ***at least*** two releases. 35 | 36 | ## Motivation 37 | 38 | We’re driven to remove subpath imports for these reasons: 39 | 40 | - **Simpler and more stable API**: Limiting imports to one runtime entry point reduces reliance on unstable internal modules, giving us exact control over the public API. 41 | - **Package encapsulation**: Again, keeps our internal structure flexible, letting us refactor without breaking user code. 42 | - **Simplify React Native upgrades**. 43 | - **Alignment with standards**: Modern JavaScript packages, including React, favour single entry point APIs, making React Native more consistent and intuitive. 44 | - **Reduces standards conflicts**. (e.g. under [`package.json` `"exports"` support](https://metrobundler.dev/docs/package-exports/#breaking-import-specifiers-are-matched-exactly), we can't apply [platform-specific module](https://reactnative.dev/docs/platform-specific-code) resolution on subpaths.) 45 | 46 | ### Towards a stable React Native API 47 | 48 | **Without a controlled package entry point, we cannot provide a stable React Native API.** 49 | 50 | Our vision with React Native's Stable API effort is to simplify and better define how apps and frameworks consume React Native. Eventually, these changes will let us iterate towards a stable, long-term `react-native` package we aim to keep unbroken across releases. 51 | 52 | ## Detailed design 53 | 54 | ### Clarifying scope 55 | 56 | When removing access to subpath imports, we refer to the *runtime API* of the `react-native` npm package. 57 | 58 | - **Included**: JavaScript modules imported by an app or library, that are bundled by Metro and executed at runtime. 59 | - **Not included**: Non-runtime support files such as scripts, e.g. `./cli.js`, `./jest-preset.js`, `./jest/`. 60 | 61 | In practical terms, this means imports to modules under `react-native/Libraries/*` will be removed, in favour of the **main entry point** (`react-native/index.js`). 62 | 63 | #### Removal of internal APIs is a breaking change 64 | 65 | This move, shipped first as a non-breaking deprecation, will intentionally result in breaking changes for developers. 66 | 67 | The current "public API" of `react-native` is unbounded, since any module, and any potentially internal, intermediary code can be accessed. 68 | 69 | ```ts 70 | // Before - subpath imports allowed 71 | import {Alert, AlertType} from 'react-native/Libraries/Alert/Alert'; 72 | import NativeAlertManager from 'react-native/Libraries/Alert/NativeAlertManager'; 73 | 74 | // After - must import from 'react-native' 75 | import {Alert, AlertType} from 'react-native'; 76 | // - ✅ Alert and AlertType APIs are public 77 | // - 🚫 Internal NativeAlertManager.js module is private and inaccessible 78 | ``` 79 | 80 | > [!Note] 81 | > **💡 Most apps**, if following our documented APIs, should already be using the `'react-native'` import path exclusively. 82 | 83 | ### What will be in the public API? 84 | 85 | By removing subpath imports, we will scope the `react-native` package down to a narrower, enumerable public API, using the existing `index.js` and `index.d.ts` exports as a starting point. 86 | 87 | All existing APIs exported from the main `'react-native'` import path will be **unchanged**. As of March 2025, we now define a strict list of type exports, see [`index.js.flow`](https://github.com/facebook/react-native/blob/main/packages/react-native/index.js.flow) — symbols that are not in this file will not be part of the public API. 88 | 89 | #### Framework considerations 90 | 91 | One index file for React Native's public API is our ideal final state — for apps, libraries, and [React Native Frameworks](./0759-react-native-frameworks.md). However, we may revise this decision down the line if there emerges a strong need for an escape hatch for specific internals. The intent is for us to narrow from all files → explicit entry point(s) to our packages. 92 | 93 | This will be open to input during the API consultation period, and we'll directly engage with Expo and our partners around this. 94 | 95 | #### First party usages 96 | 97 | We will also address any first party usages of subpath imports within React Native itself — making sure these APIs are exposed on the main module. 98 | 99 | Already actioned: 100 | 101 | - `CodegenTypes`, `codegenNativeComponent`, `codegenNativeCommands` (https://github.com/facebook/react-native/pull/49854). 102 | 103 | ### Performance considerations 104 | 105 | Routing all module imports through one index file has potential performance implications. We believe these will be negligible. 106 | 107 | - **Existing index optimisations unchanged**: The shape of `index.js` is unchanged, preserving the existing inline `require()` pattern for internal imports. Metro will correctly optimise these imports in the production bundle. 108 | - (Shakeable ESM imports, which do not rely on this special pattern, are something we want to pursue in Metro down the line.) 109 | 110 | ## Adoption strategy 111 | 112 | The impact of these changes is potentially considerable, particularly for React Native libraries and Frameworks. After an initial deprecation, we will take our time and listen to the ecosystem before shipping a hard removal. 113 | 114 | - **Deprecate in 0.80**, with an API consultation period of at least two major releases. 115 | - **Offer tools**: Provide migration aids, including dev-mode warnings, an ESLint rule, and via related TypeScript changes. 116 | - **Fully remove when confident**. 117 | 118 | ### Deprecation period 119 | 120 | #### Dedicated announcement post 121 | 122 | We'll communicate the impact of this change to users in the 0.80 release post on the React Native website, as well as a dedicated deep-dive post. 123 | 124 | #### Dedicated GitHub discussion thread 125 | 126 | As well as monitoring new GitHub issues, this thread (maintained by [@huntie](https://github.com/huntie)) will form the main public communication channel during our API consultation period. 127 | 128 | https://github.com/react-native-community/discussions-and-proposals/discussions/893 129 | 130 | #### Lint and runtime warnings in 0.80 131 | 132 | We aim to ship development-time warnings both in ESLint (surfacing in text editors/command line) and via a dev-only Metro transform plugin (surfacing in the JavaScript console). 133 | 134 | ```ts 135 | import {Alert} from 'react-native/Libraries/Alert/Alert'; 136 | // ^ Warning: Deep imports from React Native are deprecated. 137 | // 'Alert' should be imported from 'react-native'. 138 | // Autofix: 139 | // import {Alert} from 'react-native'; 140 | ``` 141 | 142 | **Under the hood**: As we are unsure about the % usage of [@react-native/eslint-config](https://www.npmjs.com/package/@react-native/eslint-config), we believe integrating via Metro is important for consistent visibility. 143 | 144 | #### Removing subpaths from our TypeScript API (opt-in) 145 | 146 | See [Parallel effort: Strict TypeScript API](#parallel-effort-strict-typescript-api). 147 | 148 | ### Eventual strong enforcement 149 | 150 | Again, it's important that we give the community sufficient time to adapt to this change before we action a hard removal — we anticipate this will be during **H2 2025**. 151 | 152 | Once the API consultation period is over, and we have reasonable confidence from libraries and partners, we'll action a hard removal of subpath imports via the [`package.json` `"exports"` spec](https://nodejs.org/docs/latest-v18.x/api/packages.html#exports). 153 | 154 | **Future `react-native` package.json** 155 | 156 | This will functionally disallow unlisted subpath imports under TypeScript, Metro, Jest, Node.js, and others. 157 | 158 | ```json5 159 | { 160 | "exports": { 161 | ".": "./index.js", // 🚫 Subpath imports disallowed 162 | // ... (non-runtime exports) 163 | } 164 | } 165 | ``` 166 | 167 | --- 168 | 169 | ## Parallel effort: Strict TypeScript API 170 | 171 | > 🟢 In active development as of January 2025. 172 | 173 | #### Discouraging use by removing subpaths under TypeScript 174 | 175 | A parallel part of our adoption strategy is a new version of React Native's TypeScript API, auto-translated from the source codebase in Flow. While a separate effort, this forms an incentivising mechanism for removing subpath imports, on top of console and ESLint warnings. 176 | 177 | This new API will no longer expose internal `react-native` modules under TypeScript — resulting in type errors against existing uses, and preventing new deep imports which may have occurred from auto-importing in the past. 178 | 179 | #### User opt-in 180 | 181 | By default, TypeScript will continue to use the existing manually defined types included in the `react-native` package, which allow subpaths. 182 | 183 | When we ship the new Strict TypeScript API, it will be available as a user opt-in — by specifying the `"react-native-strict-api"` condition in a project's `tsconfig.json`. 184 | 185 | ```json 186 | { 187 | "compilerOptions": { 188 | "customConditions": ["react-native-strict-api"] 189 | } 190 | } 191 | ``` 192 | 193 | See [TSConfig Reference - `customConditions`](https://www.typescriptlang.org/tsconfig/#customConditions). 194 | 195 | Under the hood, this opt-in will be implemented in React Native via a lenient `package.json` `"exports"` mapping, exposing only `"." → "types_generated/index.d.ts"` under this condition. 196 | 197 | ```json5 198 | { 199 | "exports": { 200 | ".": { 201 | "react-native-strict-api": "./types_generated/index.d.ts", 202 | "default": "./index.js" 203 | }, 204 | "./*": { 205 | "react-native-strict-api": null, // ← 🚫 Subpath imports disallowed 206 | "default": "./*.js" 207 | } 208 | } 209 | } 210 | ``` 211 | 212 | 213 | - The scope of this opt-in will be for the immediately analysed TypeScript project root, and will have no impact at runtime or on dependent projects. 214 | - Having an user opt-in will be necessary both for subpath import removal, as well as breaking changes to some type shapes now generated from source (increasing correctness, consistency, and ergonomics). 215 | - As with subpath import deprecation, we may consider an escape hatch for Frameworks, based on feedback. 216 | 217 | #### Final state (coordinated removal of subpath imports) 218 | 219 | The final state (potentially with a preceding opt-out state) will be a hard rollout of the new types in a future version of React Native, aligned with when we remove subpath imports in our `"exports"` mapping. 220 | 221 | ```json5 222 | { 223 | "exports": { 224 | ".": { 225 | "types": "./types_generated/index.d.ts", 226 | "default": "./index.js" 227 | } 228 | } 229 | } 230 | ``` 231 | -------------------------------------------------------------------------------- /proposals/README.md: -------------------------------------------------------------------------------- 1 | # Planning and Proposals for React Native 2 | 3 | Many changes, including bug fixes and documentation improvements, can be implemented and reviewed via the normal GitHub pull request workflow in the React Native project. Some changes are substantial enough to need additional planning, and others have enough impact to need additional community input. We ask that both of these use the following proposal format below when practical. 4 | 5 | [Active Proposal List](https://github.com/react-native-community/discussions-and-proposals/pulls?q=is%3Aopen) 6 | 7 | ## The process 8 | 9 | In short, to make a major change to React Native, make a proposal and submit it as a pull request. The community will review it and may opt to approve it. At that point, the proposal is accepted and may be implemented. 10 | 11 | - Fork this repository [react-native-community/discussions-and-proposals](http://github.com/react-native-community/discussions-and-proposals) 12 | - Copy `proposals/0000-template.md` to `proposals/0000-my-feature.md` (where 'my-feature' is the title in kebab case; don't assign a number yet). 13 | - Fill in the proposal. Put care into the details: **Proposals that do not present convincing motivation, demonstrate understanding of the impact of the design, or are disingenuous about the drawbacks or alternatives tend to be poorly-received**. 14 | - Submit a pull request. As a pull request, the proposal will receive feedback from the larger community, and the author should be prepared to revise it in response. 15 | - Build consensus and integrate feedback. Proposals that have broad support are much more likely to make progress than those that don't receive any comments. 16 | - Eventually, the team will decide whether the proposal is a candidate for adoption. 17 | - A proposal can be modified based upon feedback from the team and community. Significant modifications may trigger a new final comment period. 18 | - A proposal may be rejected by the team after public discussion has settled and comments have been made summarizing the rationale for rejection. A member of the team should then close the associated pull request. 19 | - A proposal may be accepted. A team member will merge the proposal's associated pull request, at which point the proposal will become adopted. 20 | 21 | ## After acceptance 22 | 23 | Once a proposal is accepted, then authors may implement it. This may mean submitting a pull request to the React Native repository or putting some other process into place. Acceptance however does not mean that resources are committed to the work; instead it means that the group is open to the change taking place. 24 | 25 | Modifications to accepted proposals can be done in followup PRs. 26 | 27 | ## Implementing a proposal 28 | 29 | The author of a proposal is not obligated to implement it. Of course, the proposal author (like any other community member) is welcome to post an implementation for review. 30 | 31 | ## Reviewing a proposal 32 | 33 | Periodically, the team will attempt to review the active proposals. We try to accept proposals at the monthly team meeting, and actions are recorded in the meeting minutes. Every accepted feature should have a core team champion, who will represent the feature and its progress. 34 | 35 | **React Native's proposal process owes its inspiration to the [Rust RFC process], the [Ember RFC process], the [Yarn RFC process], and the [React RFC process]** 36 | 37 | [yarn rfc process]: https://github.com/yarnpkg/rfcs 38 | [react rfc process]: https://github.com/reactjs/rfcs 39 | [rust rfc process]: https://github.com/rust-lang/rfcs 40 | [ember rfc process]: https://github.com/emberjs/rfcs 41 | -------------------------------------------------------------------------------- /proposals/assets/0006-current-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/proposals/assets/0006-current-status.png -------------------------------------------------------------------------------- /proposals/assets/0006-proposal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/proposals/assets/0006-proposal.png -------------------------------------------------------------------------------- /proposals/assets/0641-one-click-hermes-debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/proposals/assets/0641-one-click-hermes-debug.png -------------------------------------------------------------------------------- /proposals/assets/0744-fabric-current-async-update-embedded-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/proposals/assets/0744-fabric-current-async-update-embedded-diagram.png -------------------------------------------------------------------------------- /proposals/assets/0744-fabric-event-loop-async-update-embedded-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/proposals/assets/0744-fabric-event-loop-async-update-embedded-diagram.png -------------------------------------------------------------------------------- /proposals/assets/0744-fabric-event-loop-sync-update-embedded-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-community/discussions-and-proposals/094e7c9b0809ed33b45586b722459408086f07c7/proposals/assets/0744-fabric-event-loop-sync-update-embedded-diagram.png --------------------------------------------------------------------------------