diff --git a/docs/activityindicator.md b/docs/activityindicator.md
index fc8edca4e25..c9d03b73021 100644
--- a/docs/activityindicator.md
+++ b/docs/activityindicator.md
@@ -78,6 +78,12 @@ Whether the indicator should hide when not animating.
---
+### `ref`
+
+A ref setter that will be assigned an [element node](element-nodes) when mounted.
+
+---
+
### `size`
Size of the indicator.
diff --git a/docs/document-nodes.md b/docs/document-nodes.md
new file mode 100644
index 00000000000..978ef87a1f8
--- /dev/null
+++ b/docs/document-nodes.md
@@ -0,0 +1,75 @@
+---
+id: document-nodes
+title: Document nodes
+---
+
+Document nodes represent a complete native view tree. Apps using native navigation would provide a separate document node for each screen. Apps not using native navigation would generally provide a single document for the whole app (similar to single-page apps on Web).
+
+```SnackPlayer ext=js&name=Document%20instance%20example
+import * as React from 'react';
+import {Text, TextInput, View} from 'react-native';
+
+function MyComponent(props) {
+ return (
+
+ Start typing below
+
+
+ )
+}
+
+export default function AccessingDocument() {
+ const ref = React.useRef(null);
+
+ React.useEffect(() => {
+ // Get the main text input in the screen and focus it after initial load.
+ const element = ref.current;
+ const doc = element.ownerDocument;
+ const textInput = doc.getElementById('main-text-input');
+ textInput?.focus();
+ }, []);
+
+ return (
+
+ );
+}
+```
+
+---
+
+## Reference
+
+### Web-compatible API
+
+From [`Document`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement):
+
+- Properties
+ - [`childElementCount`](https://developer.mozilla.org/en-US/docs/Web/API/Document/childElementCount)
+ - [`children`](https://developer.mozilla.org/en-US/docs/Web/API/Document/children)
+ - [`documentElement`](https://developer.mozilla.org/en-US/docs/Web/API/Document/documentElement)
+ - [`firstElementChild`](https://developer.mozilla.org/en-US/docs/Web/API/Document/firstElementChild)
+ - [`lastElementChild`](https://developer.mozilla.org/en-US/docs/Web/API/Document/lastElementChild)
+- Methods
+ - [`getElementById()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById)
+
+From [`Node`](https://developer.mozilla.org/en-US/docs/Web/API/Node):
+
+- Properties
+ - [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
+ - [`firstChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)
+ - [`isConnected`](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected)
+ - [`lastChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/lastChild)
+ - [`nextSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)
+ - [`nodeName`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName)
+ - [`nodeType`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType)
+ - [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue)
+ - [`ownerDocument`](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument)
+ - [`parentElement`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement)
+ - [`parentNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode)
+ - [`previousSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling)
+ - [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
+- Methods
+ - [`compareDocumentPosition()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition)
+ - [`contains()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
+ - [`getRootNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
+ - [`hasChildNodes()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/hasChildNodes)
diff --git a/docs/element-nodes.md b/docs/element-nodes.md
new file mode 100644
index 00000000000..1c0d639f3f0
--- /dev/null
+++ b/docs/element-nodes.md
@@ -0,0 +1,135 @@
+---
+id: element-nodes
+title: Element nodes
+---
+
+Element nodes represent native components in the native view tree (similar to [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) nodes on Web).
+
+They are provided by all native components, and by many built-in components, via refs:
+
+```SnackPlayer ext=js&name=Element%20instances%20example
+import * as React from 'react';
+import { View, SafeAreaView, StyleSheet, Text } from 'react-native';
+
+const ViewWithRefs = () => {
+ const ref = React.useRef(null);
+ const [viewInfo, setViewInfo] = React.useState('');
+
+ React.useEffect(() => {
+ // `element` is an object implementing the interface described here.
+ const element = ref.current;
+ const rect = JSON.stringify(element.getBoundingClientRect());
+ setViewInfo(
+ `Bounding rect is: ${rect}.\nText content is: ${element.textContent}`,
+ );
+ }, []);
+
+ return (
+
+
+ Hello world!
+
+ {viewInfo}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ content: {
+ padding: 10,
+ backgroundColor: 'gray',
+ },
+});
+
+export default ViewWithRefs;
+```
+
+:::info
+Note that some built-in components are only a container for other components (including native components). For example, `ScrollView` internally renders a native scroll view and a native view, which are accessible through the ref it provides using methods like `getNativeScrollRef()` and `getInnerViewRef()`.
+:::
+
+---
+
+## Reference
+
+### Web-compatible API
+
+From [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement):
+
+- Properties
+ - [`offsetHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight)
+ - [`offsetLeft`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft)
+ - [`offsetParent`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent)
+ - [`offsetTop`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop)
+ - [`offsetWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth)
+- Methods
+ - [`blur()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur).
+ - [`focus()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus).
+ - ⚠️ The `options` parameter is not supported.
+
+From [`Element`](https://developer.mozilla.org/en-US/docs/Web/API/Element):
+
+- Properties
+ - [`childElementCount`](https://developer.mozilla.org/en-US/docs/Web/API/Element/childElementCount)
+ - [`children`](https://developer.mozilla.org/en-US/docs/Web/API/Element/children)
+ - [`clientHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight)
+ - [`clientLeft`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientLeft)
+ - [`clientTop`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientTop)
+ - [`clientWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth)
+ - [`firstElementChild`](https://developer.mozilla.org/en-US/docs/Web/API/Element/firstElementChild)
+ - [`id`](https://developer.mozilla.org/en-US/docs/Web/API/Element/id)
+ - ℹ️ Returns the value of the `id` or `nativeID` props.
+ - [`lastElementChild`](https://developer.mozilla.org/en-US/docs/Web/API/Element/lastElementChild)
+ - [`nextElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Element/nextElementSibling)
+ - [`nodeName`](https://developer.mozilla.org/en-US/docs/Web/API/Element/nodeName)
+ - [`nodeType`](https://developer.mozilla.org/en-US/docs/Web/API/Element/nodeType)
+ - [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Element/nodeValue)
+ - [`previousElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Element/previousElementSibling)
+ - [`scrollHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight)
+ - [`scrollLeft`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft)
+ - ⚠️ For built-in components, only `ScrollView` instances can return a value other than zero.
+ - [`scrollTop`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop)
+ - ⚠️ For built-in components, only `ScrollView` instances can return a value other than zero.
+ - [`scrollWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollWidth)
+ - [`tagName`](https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName)
+ - ℹ️ Returns a normalized native component name prefixed with `RN:`, like `RN:View`.
+ - [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Element/textContent)
+- Methods
+ - [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect)
+ - [`hasPointerCapture()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/hasPointerCapture)
+ - [`setPointerCapture()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture)
+ - [`releasePointerCapture()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/releasePointerCapture)
+
+From [`Node`](https://developer.mozilla.org/en-US/docs/Web/API/Node):
+
+- Properties
+ - [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
+ - [`firstChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)
+ - [`isConnected`](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected)
+ - [`lastChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/lastChild)
+ - [`nextSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)
+ - [`nodeName`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName)
+ - [`nodeType`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType)
+ - [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue)
+ - [`ownerDocument`](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument)
+ - ℹ️ Will return the [document instance](/docs/next/document-instances) where this component was rendered.
+ - [`parentElement`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement)
+ - [`parentNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode)
+ - [`previousSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling)
+ - [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
+- Methods
+ - [`compareDocumentPosition()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition)
+ - [`contains()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
+ - [`getRootNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
+ - ℹ️ Will return a reference to itself if the component is not mounted.
+ - [`hasChildNodes()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/hasChildNodes)
+
+### Legacy API
+
+- [`measure()`](/docs/next/legacy/direct-manipulation#measurecallback)
+- [`measureInWindow()`](/docs/next/legacy/direct-manipulation#measureinwindowcallback)
+- [`measureLayout()`](/docs/next/legacy/direct-manipulation#measurelayoutrelativetonativecomponentref-onsuccess-onfail)
+- [`setNativeProps()`](/docs/next/legacy/direct-manipulation#setnativeprops-with-touchableopacity)
diff --git a/docs/image.md b/docs/image.md
index 9b0ba6446e3..5f6a2a5b1ad 100644
--- a/docs/image.md
+++ b/docs/image.md
@@ -334,6 +334,12 @@ A string indicating which referrer to use when fetching the resource. Sets the v
---
+### `ref`
+
+A ref setter that will be assigned an [element node](element-nodes) when mounted.
+
+---
+
### `resizeMethod`
Android
The mechanism that should be used to resize the image when the image's dimensions differ from the image view's dimensions. Defaults to `auto`.
diff --git a/docs/imagebackground.md b/docs/imagebackground.md
index eba3b41b683..6670fd3b632 100644
--- a/docs/imagebackground.md
+++ b/docs/imagebackground.md
@@ -71,11 +71,7 @@ Inherits [Image Props](image.md#props).
### `imageRef`
-Allows to set a reference to the inner `Image` component
-
-| Type |
-| ------------------------------------------------------------- |
-| [Ref](https://react.dev/learn/manipulating-the-dom-with-refs) |
+A ref setter that will be assigned the [element node](element-nodes) of the inner `Image` component when mounted.
---
diff --git a/docs/modal.md b/docs/modal.md
index 66e1727be29..739be7205c3 100644
--- a/docs/modal.md
+++ b/docs/modal.md
@@ -189,6 +189,12 @@ This requires you to implement the `onRequestClose` prop to handle the dismissal
---
+### `ref`
+
+A ref setter that will be assigned an [element node](element-nodes) when mounted.
+
+---
+
### `onRequestClose`
The `onRequestClose` callback is called when the user taps the hardware back button on Android or the menu button on Apple TV. Because of this required prop, be aware that `BackHandler` events will not be emitted as long as the modal is open.
diff --git a/docs/nodes.md b/docs/nodes.md
new file mode 100644
index 00000000000..1c8a88ba918
--- /dev/null
+++ b/docs/nodes.md
@@ -0,0 +1,18 @@
+---
+id: nodes
+title: Nodes from refs
+---
+
+React Native apps render a native view tree that represents the UI, similar to how React DOM does on Web (the DOM tree). React Native provides imperative access to this tree via [refs](https://react.dev/learn/manipulating-the-dom-with-refs), which are returned by all native components (including those rendered by built-in components like [`View`](/docs/next/view)).
+
+React Native provides 3 types of nodes:
+
+- [Elements](/docs/next/element-nodes): element nodes represent native components in the native view tree (similar to [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) nodes on Web). They are provided by all native components via refs.
+- [Text](/docs/next/text-nodes): text nodes represent raw text content on the tree (similar to [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text) nodes on Web). They are not directly accessible via `refs`, but can be accessed using methods like [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes) on element refs.
+- [Documents](/docs/next/document-nodes): document nodes represent a complete native view tree (similar to [`Document`](https://developer.mozilla.org/en-US/docs/Web/API/Document) nodes on Web). Like text nodes, they can only be accessed through other nodes, using properties like [`ownerDocument`](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument).
+
+As on Web, these nodes can be used to traverse the rendered UI tree, access layout information or execute imperative operations like `focus`.
+
+:::info
+**Unlike on Web, these nodes do not allow mutation** (e.g.: [`node.appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild)), as the tree contents are fully managed by the React renderer.
+:::
diff --git a/docs/switch.md b/docs/switch.md
index fcbaae7b1de..4f9055c6256 100644
--- a/docs/switch.md
+++ b/docs/switch.md
@@ -96,6 +96,12 @@ Invoked when the user tries to change the value of the switch. Receives the new
---
+### `ref`
+
+A ref setter that will be assigned an [element node](element-nodes) when mounted.
+
+---
+
### `thumbColor`
Color of the foreground switch grip. If this is set on iOS, the switch grip will lose its drop shadow.
diff --git a/docs/text-nodes.md b/docs/text-nodes.md
new file mode 100644
index 00000000000..7fdbacf550f
--- /dev/null
+++ b/docs/text-nodes.md
@@ -0,0 +1,86 @@
+---
+id: text-nodes
+title: Text nodes
+---
+
+Text nodes represent raw text content on the tree (similar to [`Text`](https://developer.mozilla.org/en-US/docs/Web/API/Text) nodes on Web). They are not directly accessible via `refs`, but can be accessed using methods like [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes) on element refs.
+
+```SnackPlayer ext=js&name=Text%20instances%20example
+import * as React from 'react';
+import { SafeAreaView, StyleSheet, Text } from 'react-native';
+
+const TextWithRefs = () => {
+ const ref = React.useRef(null);
+ const [viewInfo, setViewInfo] = React.useState('');
+
+ React.useEffect(() => {
+ // `textElement` is an object implementing the interface described here.
+ const textElement = ref.current;
+ const textNode = textElement.childNodes[0];
+ setViewInfo(
+ `Text content is: ${textNode.nodeValue}`,
+ );
+ }, []);
+
+ return (
+
+
+ Hello world!
+
+ {viewInfo}
+
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ },
+ content: {
+ padding: 10,
+ backgroundColor: 'gray',
+ },
+});
+
+export default TextWithRefs;
+```
+
+---
+
+## Reference
+
+### Web-compatible API
+
+From [`CharacterData`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData):
+
+- Properties
+ - [`data`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/data)
+ - [`length`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/length)
+ - [`nextElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/nextElementSibling)
+ - [`previousElementSibling`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/previousElementSibling)
+- Methods
+ - [`substringData()`](https://developer.mozilla.org/en-US/docs/Web/API/CharacterData/substringData)
+
+From [`Node`](https://developer.mozilla.org/en-US/docs/Web/API/Node):
+
+- Properties
+ - [`childNodes`](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
+ - [`firstChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild)
+ - [`isConnected`](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected)
+ - [`lastChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node/lastChild)
+ - [`nextSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling)
+ - [`nodeName`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName)
+ - [`nodeType`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType)
+ - [`nodeValue`](https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue)
+ - [`ownerDocument`](https://developer.mozilla.org/en-US/docs/Web/API/Node/ownerDocument)
+ - ℹ️ Will return the [document instance](/docs/next/document-instances) where this component was rendered.
+ - [`parentElement`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement)
+ - [`parentNode`](https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode)
+ - [`previousSibling`](https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling)
+ - [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
+- Methods
+ - [`compareDocumentPosition()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition)
+ - [`contains()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
+ - [`getRootNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
+ - ℹ️ Will return a reference to itself if the component is not mounted.
+ - [`hasChildNodes()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/hasChildNodes)
diff --git a/docs/text.md b/docs/text.md
index b6a0202e2e9..c45892ce2a4 100644
--- a/docs/text.md
+++ b/docs/text.md
@@ -638,6 +638,14 @@ When the scroll view is disabled, this defines how far your touch may move off o
---
+### `ref`
+
+A ref setter that will be assigned an [element node](element-nodes) when mounted.
+
+Note that `Text` components don't provide text nodes, the same way that paragraph elements (``) on Web are element nodes instead of text nodes. Text nodes can be found as their child nodes instead.
+
+---
+
### `role`
`role` communicates the purpose of a component to the user of an assistive technology. Has precedence over the [`accessibilityRole`](text#accessibilityrole) prop.
diff --git a/docs/touchablehighlight.md b/docs/touchablehighlight.md
index cd6313e66fe..98ea0823783 100644
--- a/docs/touchablehighlight.md
+++ b/docs/touchablehighlight.md
@@ -122,6 +122,12 @@ Called immediately after the underlay is shown.
---
+### `ref`
+
+A ref setter that will be assigned an [element node](element-nodes) when mounted.
+
+---
+
### `style`
| Type |
diff --git a/docs/touchableopacity.md b/docs/touchableopacity.md
index 025f38aa4c9..72af0bc5f49 100644
--- a/docs/touchableopacity.md
+++ b/docs/touchableopacity.md
@@ -143,3 +143,9 @@ TV next focus up (see documentation for the View component).
| Type |
| ------ |
| number |
+
+---
+
+### `ref`
+
+A ref setter that will be assigned an [element node](element-nodes) when mounted.
diff --git a/docs/view.md b/docs/view.md
index b967c0a64b6..3fd3c7fb4bd 100644
--- a/docs/view.md
+++ b/docs/view.md
@@ -729,6 +729,12 @@ Controls whether the `View` can be the target of touch events.
---
+### `ref`
+
+A ref setter that will be assigned an [element node](element-nodes) when mounted.
+
+---
+
### `removeClippedSubviews`
This is a reserved performance property exposed by `RCTView` and is useful for scrolling content when there are many subviews, most of which are offscreen. For this property to be effective, it must be applied to a view that contains many subviews that extend outside its bound. The subviews must also have `overflow: hidden`, as should the containing view (or one of its superviews).
diff --git a/website/sidebars.ts b/website/sidebars.ts
index 42c4c457ab7..dd8be8dbb40 100644
--- a/website/sidebars.ts
+++ b/website/sidebars.ts
@@ -315,6 +315,7 @@ export default {
items: ['inputaccessoryview', 'safeareaview'],
},
],
+ Refs: ['nodes', 'element-nodes', 'text-nodes', 'document-nodes'],
Props: [
'image-style-props',
'layout-props',