diff --git a/lib/shared/typeahead-utils.js b/lib/shared/typeahead-utils.js
--- a/lib/shared/typeahead-utils.js
+++ b/lib/shared/typeahead-utils.js
@@ -10,6 +10,11 @@
   +usernamePrefix: string,
 };
 
+export type Selection = {
+  +start: number,
+  +end: number,
+};
+
 function getTypeaheadUserSuggestions(
   userSearchIndex: SearchIndex,
   threadMembers: $ReadOnlyArray<RelativeMemberInfo>,
diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js
--- a/native/chat/chat-input-bar.react.js
+++ b/native/chat/chat-input-bar.react.js
@@ -43,6 +43,7 @@
   draftKeyFromThreadID,
   colorIsDark,
 } from 'lib/shared/thread-utils';
+import type { Selection } from 'lib/shared/typeahead-utils';
 import type { CalendarQuery } from 'lib/types/entry-types';
 import type { LoadingStatus } from 'lib/types/loading-types';
 import type { PhotoPaste } from 'lib/types/media-types';
@@ -84,7 +85,7 @@
 } from '../navigation/route-names';
 import { useSelector } from '../redux/redux-utils';
 import { type Colors, useStyles, useColors } from '../themes/colors';
-import type { LayoutEvent } from '../types/react-native';
+import type { LayoutEvent, SelectionChangeEvent } from '../types/react-native';
 import { type AnimatedViewStyle, AnimatedView } from '../types/styles';
 import { runTiming } from '../utils/animation-utils';
 import { ChatContext } from './chat-context';
@@ -148,6 +149,7 @@
   +text: string,
   +textEdited: boolean,
   +buttonsExpanded: boolean,
+  +selection: Selection,
 };
 class ChatInputBar extends React.PureComponent<Props, State> {
   textInput: ?React.ElementRef<typeof TextInput>;
@@ -170,6 +172,7 @@
       text: props.draft,
       textEdited: false,
       buttonsExpanded: true,
+      selection: { start: 0, end: 0 },
     };
 
     this.setUpActionIconAnimations();
@@ -568,6 +571,8 @@
             allowImagePasteForThreadID={this.props.threadInfo.id}
             value={this.state.text}
             onChangeText={this.updateText}
+            selection={this.state.selection}
+            onSelectionChange={this.updateSelection}
             placeholder="Send a message..."
             placeholderTextColor={this.props.colors.listInputButton}
             multiline={true}
@@ -609,6 +614,10 @@
     this.saveDraft(text);
   };
 
+  updateSelection: (event: SelectionChangeEvent) => void = event => {
+    this.setState({ selection: event.nativeEvent.selection });
+  };
+
   saveDraft = _throttle(text => {
     this.props.dispatch({
       type: updateDraftActionType,
diff --git a/native/components/clearable-text-input.js b/native/components/clearable-text-input.js
--- a/native/components/clearable-text-input.js
+++ b/native/components/clearable-text-input.js
@@ -6,7 +6,7 @@
 type TextInputProps = React.ElementConfig<typeof BaseTextInput>;
 export type ClearableTextInputProps = {
   ...TextInputProps,
-  textInputRef: (textInput: ?React.ElementRef<typeof BaseTextInput>) => mixed,
-  onChangeText: $NonMaybeType<$PropertyType<TextInputProps, 'onChangeText'>>,
-  value: $NonMaybeType<$PropertyType<TextInputProps, 'value'>>,
+  +textInputRef: (textInput: ?React.ElementRef<typeof BaseTextInput>) => mixed,
+  +onChangeText: $NonMaybeType<$PropertyType<TextInputProps, 'onChangeText'>>,
+  +value: $NonMaybeType<$PropertyType<TextInputProps, 'value'>>,
 };
diff --git a/native/components/clearable-text-input.react.ios.js b/native/components/clearable-text-input.react.ios.js
--- a/native/components/clearable-text-input.react.ios.js
+++ b/native/components/clearable-text-input.react.ios.js
@@ -154,6 +154,7 @@
           {...props}
           style={[props.style, styles.invisibleTextInput]}
           onChangeText={this.onOldInputChangeText}
+          onSelectionChange={this.props.onSelectionChange}
           onKeyPress={this.onOldInputKeyPress}
           onBlur={this.onOldInputBlur}
           onFocus={this.onOldInputFocus}
@@ -167,6 +168,7 @@
         onFocus={this.onFocus}
         onBlur={this.onBlur}
         onChangeText={this.props.onChangeText}
+        onSelectionChange={this.props.onSelectionChange}
         key={this.state.textInputKey}
         ref={this.textInputRef}
       />,
diff --git a/native/components/clearable-text-input.react.js b/native/components/clearable-text-input.react.js
--- a/native/components/clearable-text-input.react.js
+++ b/native/components/clearable-text-input.react.js
@@ -60,6 +60,7 @@
         <TextInput
           {...props}
           onChangeText={this.onChangeText}
+          onSelectionChange={this.props.onSelectionChange}
           ref={this.textInputRef}
         />
       </View>
diff --git a/native/types/react-native.js b/native/types/react-native.js
--- a/native/types/react-native.js
+++ b/native/types/react-native.js
@@ -15,6 +15,8 @@
   BlurEvent,
 } from 'react-native/Libraries/Components/TextInput/TextInput';
 
+export type { SelectionChangeEvent } from 'react-native/Libraries/Components/TextInput/TextInput';
+
 export type { NativeMethods } from 'react-native/Libraries/Renderer/shims/ReactNativeTypes';
 
 export type { KeyboardEvent } from 'react-native/Libraries/Components/Keyboard/Keyboard';