diff --git a/native/user-profile/user-profile-avatar.react.js b/native/user-profile/user-profile-avatar.react.js
new file mode 100644
--- /dev/null
+++ b/native/user-profile/user-profile-avatar.react.js
@@ -0,0 +1,73 @@
+// @flow
+
+import { useNavigation, useRoute } from '@react-navigation/native';
+import invariant from 'invariant';
+import * as React from 'react';
+import { View, TouchableOpacity } from 'react-native';
+
+import { userProfileUserInfoContainerHeight } from './user-profile-constants.js';
+import UserAvatar from '../avatars/user-avatar.react.js';
+import { OverlayContext } from '../navigation/overlay-context.js';
+import { UserProfileAvatarModalRouteName } from '../navigation/route-names.js';
+
+// We need to set onAvatarLayout in order to allow .measure() to be on the ref
+const onAvatarLayout = () => {};
+
+type Props = {
+  userID: ?string,
+};
+
+function UserProfileAvatar(props: Props): React.Node {
+  const { userID } = props;
+
+  const { navigate } = useNavigation();
+  const route = useRoute();
+
+  const overlayContext = React.useContext(OverlayContext);
+
+  const avatarRef = React.useRef();
+
+  const onPressAvatar = React.useCallback(() => {
+    invariant(overlayContext, 'UserProfileAvatar should have OverlayContext');
+    overlayContext.setScrollBlockingModalStatus('open');
+
+    const currentAvatarRef = avatarRef.current;
+    if (!currentAvatarRef) {
+      return;
+    }
+
+    currentAvatarRef.measure((x, y, width, height, pageX, pageY) => {
+      const coordinates = {
+        x: pageX,
+        y: pageY,
+        width,
+        height,
+      };
+
+      const verticalBounds = {
+        height: userProfileUserInfoContainerHeight,
+        y: pageY,
+      };
+
+      navigate<'UserProfileAvatarModal'>({
+        name: UserProfileAvatarModalRouteName,
+        params: {
+          presentedFrom: route.key,
+          initialCoordinates: coordinates,
+          verticalBounds,
+          userID,
+        },
+      });
+    });
+  }, [navigate, overlayContext, route.key, userID]);
+
+  return (
+    <TouchableOpacity onPress={onPressAvatar}>
+      <View ref={avatarRef} onLayout={onAvatarLayout}>
+        <UserAvatar size="L" userID={userID} />
+      </View>
+    </TouchableOpacity>
+  );
+}
+
+export default UserProfileAvatar;
diff --git a/native/user-profile/user-profile.react.js b/native/user-profile/user-profile.react.js
--- a/native/user-profile/user-profile.react.js
+++ b/native/user-profile/user-profile.react.js
@@ -12,6 +12,7 @@
 import type { UserInfo } from 'lib/types/user-types';
 import sleep from 'lib/utils/sleep.js';
 
+import UserProfileAvatar from './user-profile-avatar.react.js';
 import {
   userProfileUserInfoContainerHeight,
   userProfileBottomPadding,
@@ -20,7 +21,6 @@
 } from './user-profile-constants.js';
 import UserProfileMessageButton from './user-profile-message-button.react.js';
 import UserProfileRelationshipButton from './user-profile-relationship-button.react.js';
-import UserAvatar from '../avatars/user-avatar.react.js';
 import { BottomSheetContext } from '../bottom-sheet/bottom-sheet-provider.react.js';
 import SingleLine from '../components/single-line.react.js';
 import SWMansionIcon from '../components/swmansion-icon.react.js';
@@ -160,7 +160,7 @@
     <View style={styles.container}>
       <SWMansionIcon name="menu-vertical" size={24} style={styles.moreIcon} />
       <View style={styles.userInfoContainer}>
-        <UserAvatar size="L" userID={userInfo?.id} />
+        <UserProfileAvatar userID={userInfo?.id} />
         <View style={styles.usernameContainer}>
           <SingleLine style={styles.usernameText}>{usernameText}</SingleLine>
           {copyUsernameButton}