Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,10 @@ module.exports = {
'lint/no-react-native-imports': 'off',
},
},
{
files: ['**/__docs__/*.md'],
parser: 'eslint-plugin-markdownlint/parser',
extends: ['plugin:markdownlint/recommended'],
},
],
};
24 changes: 24 additions & 0 deletions .markdownlint-cli2.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

import relativeLinksRule from 'markdownlint-rule-relative-links';

const config = {
config: {
default: true,
'heading-style': 'atx',
'line-length': false,
'relative-links': true,
},
globs: ['**/__docs__/*.md'],
ignores: ['**/node_modules'],
customRules: [relativeLinksRule],
};

export default config;
10 changes: 8 additions & 2 deletions __docs__/GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@ _This is a document about documentation (hence the file name)._
## Motivation

The goals of this documentation are:

1. To make it easier for people to understand and contribute to the React Native architecture.
2. To ensure the architecture is easy to maintain, with clearly scoped subsystems that are easy to reason about and change.

## Strategy

Our documentation supports the following use cases:
1. [Exploration based] I want to understand how React Native works and learn about its different parts. I want to explore.
2. [Goal based] I want to solve a problem and change something specific, so I want to understand what I should change and how the system I need to change works. I need to understand how other systems depend on this.

1. (Exploration based) I want to understand how React Native works and learn about its different parts. I want to explore.
2. (Goal based) I want to solve a problem and change something specific, so I want to understand what I should change and how the system I need to change works. I need to understand how other systems depend on this.

To support the first case, we provide a single entrypoint for the whole documentation, which will be the first step in a tree of docs with links to parents and children:

- `<root>/__docs__/README.md` (with links to subsystems 1, 2, etc.)
- `Subsystem 1/__docs__/README.md` (with links to root and subsystems 1.1, 1.2, etc.)
- `Subsystem 1.1/__docs__/README.md` (with links to subsystem 1 and subsystems 1.1.1, 1.1.2, etc.)
Expand All @@ -26,6 +29,7 @@ This structure will make it possible for the user to navigate across the documen
To support the second use case, focusing on a specific subsystem, we will describe what are the relationships between that subsystem and others, to make sure that changes to its API are understood, and that usages of other subsystems are considered.

The use of the `__docs__` directory (inspired by Python) has 2 goals:

1. Make the documentation easy to find in the directory, by generally appearing at the top of the directory (similar to `__tests__`).
2. Grouping the documentation itself and its assets (images, diagrams, etc.).

Expand All @@ -44,6 +48,7 @@ If you include Excalidraw diagrams, make sure to export an SVG image from the we
The level of granularity in the definition of the subsystems should be enough to correctly describe how React Native works, but not so detailed that any changes in the code require changes in the documentation.

Examples:

- Requires updating the docs:
- Adding a new major feature or API.
- Adding a new relevant dependency. Adding a dependency to helper functions does not count as relevant.
Expand All @@ -55,5 +60,6 @@ Examples:
### Location

When a specific subsystem exists in multiple directories (e.g.: platform-specific ones, C++, JavaScript, etc.):

1. Choose one of them to place the canonical documentation (in order of preference, JavaScript -> C++ -> platform).
2. Create specific files in the rest linking to the canonical one.
2 changes: 1 addition & 1 deletion __docs__/README-template.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# _Subsystem name_

* [Main doc](../__docs__/README.md)
- [Main doc](../__docs__/README.md)

_Description of the subsystem with the necessary context._

Expand Down
1 change: 1 addition & 0 deletions __docs__/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ This repository has many different types of dependencies: build systems, externa
### Uses this

The main use cases for this repository are:

1. Developing React Native itself.
2. Testing and releasing React Native.
3. Synchronizing forks like `react-native-windows` and `react-native-macos`.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"featureflags": "yarn --cwd packages/react-native featureflags",
"lint-ci": "./.github/workflow-scripts/analyze_code.sh && yarn shellcheck",
"lint-java": "node ./scripts/lint-java.js",
"lint-markdown": "markdownlint-cli2",
"lint": "eslint .",
"prettier": "prettier --write \"./**/*.{js,md,yml,ts,tsx}\"",
"print-packages": "node ./scripts/monorepo/print",
Expand Down Expand Up @@ -74,6 +75,7 @@
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-jsx-a11y": "^6.6.0",
"eslint-plugin-lint": "^1.0.0",
"eslint-plugin-markdownlint": "^0.6.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-native": "^4.0.0",
Expand All @@ -90,6 +92,8 @@
"jest-diff": "^29.7.0",
"jest-junit": "^10.0.0",
"jest-snapshot": "^29.7.0",
"markdownlint-cli2": "^0.17.2",
"markdownlint-rule-relative-links": "^4.0.1",
"metro-babel-register": "^0.82.0",
"metro-memory-fs": "^0.82.0",
"metro-transform-plugins": "^0.82.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const viewConfig: ViewConfig = {
style: {},
},
};

var test;

// $FlowExpectedError[incompatible-type]
const internalInstanceHandle: InternalInstanceHandle = {};
// $FlowExpectedError[incompatible-type]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Android event dispatching

* [Main doc](../../../../../../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../../../../../../__docs__/README.md)

This directory contains Kotlin classes specific to Android event dispatching in the new architecture.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Feature Flags

* [Main doc](../../../../../../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../../../../../../__docs__/README.md)

This directory contains the Java/Kotlin bindings for the internal React Native feature flags system.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Feature Flags

* [Main doc](../../../../../../__docs__/README.md)
- [Main doc](../../../../../../__docs__/README.md)

This directory contains the shared C++ implementation of the internal React Native feature flags system.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Feature Flags

* [Main doc](../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../__docs__/README.md)

This directory contains the native C++ TurboModule for the internal React Native feature flags system.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# IntersectionObserver

* [Main doc](../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../__docs__/README.md)

This directory contains the native module used by the [IntersectionObserver API](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) in React Native.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Microtasks

* [Main doc](../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../__docs__/README.md)

This directory contains the native module used to implement `queueMicrotask` in React Native, which schedules microtasks in the [Event Loop](../../../renderer/runtimescheduler/__docs__/README.md).

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MutationObserver

* [Main doc](../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../__docs__/README.md)

This directory contains the native module used by the [MutationObserver API](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) in React Native.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# IntersectionObserver

* [Main doc](../../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../../__docs__/README.md)

This directory contains the C++ implementation of the [IntersectionObserver API](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) in React Native.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MutationObserver

* [Main doc](../../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../../__docs__/README.md)

This directory contains the C++ implementation of the [MutationObserver API](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) in React Native.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Event Loop

* [Main doc](../__docs__/README.md)
- [Main doc](../../../../../../../__docs__/README.md)

The Event Loop is the formalization of the execution model for JavaScript in React Native, and how that model synchronizes with rendering work in the host platform.

Its main goals are:

- To make the behavior of the framework more predictable, to help developers build more reliable and performant apps.
- To increase the alignment with Web specifications, to simplify the adoption of Web APIs in React Native.
- [Secondary] Provide a solid foundation for general performance optimizations relying on better scheduling or sequencing.
- (Secondary) Provide a solid foundation for general performance optimizations relying on better scheduling or sequencing.

The implementation of the event loop in React Native is aligned with [its definition in the HTML specification](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model). React Native only implements a subset of it, in order to support its existing semantics and APIs.

Expand All @@ -17,12 +18,14 @@ The implementation of the event loop in React Native is aligned with [its defini
## Usage

The event loop is an implementation detail so it is not used directly, but several APIs integrate deeply with it:
- State updates processed by React are scheduled to be flushed (rendered in the host platform) at the end of the current event loop tick.
- Promises, `queueMicrotask` and APIs like `MutationObserver` add microtasks to the microtask queue, processed as part of the current event loop tick.
- Timers and APIs like `requestIdleCallback` schedule tasks to be processed by the event loop. In the case of `requestIdleCallback`, the tasks are scheduled with specific priorities.
- `PerformanceObserver` entries like `longtask` and `event` provide timing information about different parts of the event loop.

* State updates processed by React are scheduled to be flushed (rendered in the host platform) at the end of the current event loop tick.
* Promises, `queueMicrotask` and APIs like `MutationObserver` add microtasks to the microtask queue, processed as part of the current event loop tick.
* Timers and APIs like `requestIdleCallback` schedule tasks to be processed by the event loop. In the case of `requestIdleCallback`, the tasks are scheduled with specific priorities.
* `PerformanceObserver` entries like `longtask` and `event` provide timing information about different parts of the event loop.

One of the most important semantics of the event loop is the **atomicity of UI updates in tasks**. All changes to the UI triggered from JavaScript in a task (processing state updates in React, dispatching view commands, etc.) are always flushed together to the host platform, so the UI is never updated with partial work done within a task. For example:

1. We dispatch an event to JavaScript and execute one or more event handlers.
2. Those event handlers do one or more state updates in React. React schedules a microtask to process them.
3. In a microtask, React processes all those state updates together, re-rendering the necessary components and committing at the end.
Expand Down Expand Up @@ -73,6 +76,7 @@ function Content(props) {
The conceptual model is **aligned with [the model on the Web](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model)** (from which it borrows some concepts and steps), while **still benefiting from the React Native threading model**.

The event loop continuously goes through these steps (in what we refer to as an "event loop tick"):

1. Select the next task to execute among all tasks waiting for execution.
2. Execute the selected task.
3. Execute **all** scheduled microtasks.
Expand All @@ -89,6 +93,7 @@ One of the key benefits of this model is that each **event loop iteration repres
On the Web, task selection is an implementation detail left to browsers to decide.

In React Native, we rely on `RuntimeScheduler` for task selection, which already supports the execution of tasks with priorities. The criteria it uses is:

1. If there are expired tasks, select expired tasks in the order in which they expired.
2. Otherwise, select tasks by priority, in the order in which they were scheduled.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Feature Flags

* [Main doc](../../../../../__docs__/README.md)
- [Main doc](../../../../../__docs__/README.md)

This directory contains the flag definitions and codegen for the internal React Native feature flags system.

Expand Down
27 changes: 15 additions & 12 deletions packages/react-native/src/private/featureflags/__docs__/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Feature Flags

* [Main doc](../../../../../../__docs__/README.md)
- [Main doc](../../../../../../__docs__/README.md)

Feature flags are values that determine the behavior of specific parts of React
Native. This directory contains the configuration for those values, and scripts
to generate files for different languages to access and customize them.

There are 2 types of feature flags:
* Common: can be accessed from any language and they provide consistent values

- Common: can be accessed from any language and they provide consistent values
everywhere.
* JS-only: they can only be accessed and customized from JavaScript.
- JS-only: they can only be accessed and customized from JavaScript.

## Usage

Expand All @@ -19,6 +20,7 @@ The source of truth for the definition of the flags is the file
`ReactNativeFeatureFlags.config.js` in this directory.

Example contents:

```javascript
module.exports = {
common: {
Expand Down Expand Up @@ -56,7 +58,7 @@ Feature flags are cached at every layer, which prevents having to go through JNI
when accessing the values from Kotlin and through JSI when accessing the values
from JavaScript.

#### C++ / Objective-C
#### Accessing feature flags in C++ / Objective-C

```c++
#include <react/featureflags/ReactNativeFeatureFlags.h>
Expand All @@ -66,7 +68,7 @@ if (ReactNativeFeatureFlags::enableNativeBehavior()) {
}
```

#### Kotlin
#### Accessing feature flags in Kotlin

```kotlin
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
Expand All @@ -78,7 +80,7 @@ fun someMethod() {
}
```

#### JavaScript
#### Accessing feature flags in JavaScript

```javascript
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
Expand All @@ -103,7 +105,7 @@ Overrides must be applied before any of the available feature flags has been
accessed. This prevents having inconsistent behavior during the lifecycle of the
application.

#### C++/Objective-C
#### Setting feature flag overrides in C++/Objective-C

```c++
#include <react/featureflags/ReactNativeFeatureFlags.h>
Expand All @@ -121,7 +123,7 @@ class CustomReactNativeFeatureFlags : public ReactNativeFeatureFlagsDefaults {
ReactNativeFeatureFlags::override(std::make_unique<CustomReactNativeFeatureFlags>());
```

#### Kotlin
#### Setting feature flag overrides in Kotlin

```kotlin
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
Expand All @@ -134,7 +136,7 @@ fun overrideFeatureFlags() {
}
```

#### JavaScript
#### Setting feature flag overrides in JavaScript

```javascript
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
Expand All @@ -147,11 +149,12 @@ ReactNativeFeatureFlags.override({
## Design

The architecture of this feature flags system can be described as follows:
* A shared C++ core, where we provide access to the flags and allow

- A shared C++ core, where we provide access to the flags and allow
customizations.
* A Kotlin/Java interface that allows accessing and customizing the values in
- A Kotlin/Java interface that allows accessing and customizing the values in
the C++ core (via JNI).
* A JavaScript interface that allows accessing the common values (via a native
- A JavaScript interface that allows accessing the common values (via a native
module) and accessing and customizing the JS-only values.

![Diagram of the architecture of feature flags in React Native](./architecture.excalidraw.svg)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# IntersectionObserver

* [Main doc](../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../__docs__/README.md)

This directory contains the React Native implementation of the [IntersectionObserver API](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver).

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MutationObserver

* [Main doc](../../../../../../../__docs__/README.md)
- [Main doc](../../../../../../../__docs__/README.md)

This directory contains the React Native implementation of the [MutationObserver API](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver).

Expand Down
Loading