diff --git a/keyserver/src/creators/account-creator.js b/keyserver/src/creators/account-creator.js
--- a/keyserver/src/creators/account-creator.js
+++ b/keyserver/src/creators/account-creator.js
@@ -68,7 +68,9 @@
   if (request.password.trim() === '') {
     throw new ServerError('empty_password');
   }
-  const usernameRegex = hasMinCodeVersion(viewer.platformDetails, 69)
+  const usernameRegex = hasMinCodeVersion(viewer.platformDetails, {
+    native: 69,
+  })
     ? validUsernameRegex
     : oldValidUsernameRegex;
   if (request.username.search(usernameRegex) === -1) {
@@ -91,7 +93,7 @@
     reservedUsernamesSet.has(request.username.toLowerCase()) ||
     isValidEthereumAddress(request.username.toLowerCase())
   ) {
-    if (hasMinCodeVersion(viewer.platformDetails, 120)) {
+    if (hasMinCodeVersion(viewer.platformDetails, { native: 120 })) {
       throw new ServerError('username_reserved');
     } else {
       throw new ServerError('username_taken');
diff --git a/keyserver/src/creators/thread-creator.js b/keyserver/src/creators/thread-creator.js
--- a/keyserver/src/creators/thread-creator.js
+++ b/keyserver/src/creators/thread-creator.js
@@ -284,7 +284,7 @@
       const existingThreadID = existingThreadResult[0].id.toString();
 
       let calendarQuery;
-      if (hasMinCodeVersion(viewer.platformDetails, 87)) {
+      if (hasMinCodeVersion(viewer.platformDetails, { native: 87 })) {
         invariant(request.calendarQuery, 'calendar query should exist');
         calendarQuery = {
           ...request.calendarQuery,
@@ -482,7 +482,7 @@
     updatesForCurrentSession,
   );
 
-  if (hasMinCodeVersion(viewer.platformDetails, 62)) {
+  if (hasMinCodeVersion(viewer.platformDetails, { native: 62 })) {
     return {
       newThreadID: id,
       updatesResult: {
diff --git a/keyserver/src/deleters/thread-deleters.js b/keyserver/src/deleters/thread-deleters.js
--- a/keyserver/src/deleters/thread-deleters.js
+++ b/keyserver/src/deleters/thread-deleters.js
@@ -41,7 +41,7 @@
     // never receives the response
     const [{ updateInfos }, fetchThreadInfoResult] = await Promise.all([
       fetchUpdateInfoForThreadDeletion(viewer, threadID),
-      hasMinCodeVersion(viewer.platformDetails, 62)
+      hasMinCodeVersion(viewer.platformDetails, { native: 62 })
         ? undefined
         : fetchThreadInfos(viewer),
     ]);
@@ -108,7 +108,7 @@
     dbQuery(query),
   ]);
 
-  if (hasMinCodeVersion(viewer.platformDetails, 62)) {
+  if (hasMinCodeVersion(viewer.platformDetails, { native: 62 })) {
     return { updatesResult: { newUpdates: viewerUpdates } };
   }
 
diff --git a/keyserver/src/fetchers/message-fetchers.js b/keyserver/src/fetchers/message-fetchers.js
--- a/keyserver/src/fetchers/message-fetchers.js
+++ b/keyserver/src/fetchers/message-fetchers.js
@@ -429,7 +429,9 @@
   criteria: MessageSelectionCriteria,
 ): ParsedMessageSelectionCriteria {
   const minMessageTime = Date.now() - defaultMaxMessageAge;
-  const shouldApplyTimeFilter = hasMinCodeVersion(viewer.platformDetails, 130);
+  const shouldApplyTimeFilter = hasMinCodeVersion(viewer.platformDetails, {
+    native: 130,
+  });
 
   let globalTimeFilter;
   if (criteria.newerThan) {
diff --git a/keyserver/src/fetchers/thread-fetchers.js b/keyserver/src/fetchers/thread-fetchers.js
--- a/keyserver/src/fetchers/thread-fetchers.js
+++ b/keyserver/src/fetchers/thread-fetchers.js
@@ -178,12 +178,24 @@
   serverResult: FetchServerThreadInfosResult,
 ): FetchThreadInfosResult {
   const viewerID = viewer.id;
-  const codeVersionBelow70 = !hasMinCodeVersion(viewer.platformDetails, 70);
-  const codeVersionBelow87 = !hasMinCodeVersion(viewer.platformDetails, 87);
-  const codeVersionBelow102 = !hasMinCodeVersion(viewer.platformDetails, 102);
-  const codeVersionBelow104 = !hasMinCodeVersion(viewer.platformDetails, 104);
-  const codeVersionBelow209 = !hasMinCodeVersion(viewer.platformDetails, 209);
-  const codeVersionBelow213 = !hasMinCodeVersion(viewer.platformDetails, 213);
+  const codeVersionBelow70 = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 70,
+  });
+  const codeVersionBelow87 = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 87,
+  });
+  const codeVersionBelow102 = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 102,
+  });
+  const codeVersionBelow104 = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 104,
+  });
+  const codeVersionBelow209 = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 209,
+  });
+  const codeVersionBelow213 = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 213,
+  });
 
   const threadInfos = {};
   for (const threadID in serverResult.threadInfos) {
diff --git a/keyserver/src/fetchers/user-fetchers.js b/keyserver/src/fetchers/user-fetchers.js
--- a/keyserver/src/fetchers/user-fetchers.js
+++ b/keyserver/src/fetchers/user-fetchers.js
@@ -293,10 +293,9 @@
 
   const [userRow] = userResult;
 
-  const stillExpectsEmailFields = !hasMinCodeVersion(
-    viewer.platformDetails,
-    87,
-  );
+  const stillExpectsEmailFields = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 87,
+  });
 
   if (!userRow) {
     throw new ServerError('unknown_error');
@@ -342,7 +341,9 @@
     loggedInUserInfo = { ...loggedInUserInfo, avatar: clientAvatar };
   }
 
-  const featureGateSettings = !hasMinCodeVersion(viewer.platformDetails, 1000);
+  const featureGateSettings = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 1000,
+  });
 
   if (featureGateSettings) {
     return loggedInUserInfo;
diff --git a/keyserver/src/responders/user-responders.js b/keyserver/src/responders/user-responders.js
--- a/keyserver/src/responders/user-responders.js
+++ b/keyserver/src/responders/user-responders.js
@@ -372,7 +372,7 @@
 
   if (
     notAcknowledgedPolicies.length &&
-    hasMinCodeVersion(viewer.platformDetails, 181)
+    hasMinCodeVersion(viewer.platformDetails, { native: 181 })
   ) {
     const currentUserInfo = await fetchLoggedInUserInfo(viewer);
     return {
@@ -505,7 +505,7 @@
   }
   const username = request.username ?? request.usernameOrEmail;
   if (!username) {
-    if (hasMinCodeVersion(viewer.platformDetails, 150)) {
+    if (hasMinCodeVersion(viewer.platformDetails, { native: 150 })) {
       throw new ServerError('invalid_credentials');
     } else {
       throw new ServerError('invalid_parameters');
@@ -522,7 +522,7 @@
   } = await promiseAll(promises);
 
   if (userResult.length === 0) {
-    if (hasMinCodeVersion(viewer.platformDetails, 150)) {
+    if (hasMinCodeVersion(viewer.platformDetails, { native: 150 })) {
       throw new ServerError('invalid_credentials');
     } else {
       throw new ServerError('invalid_parameters');
diff --git a/keyserver/src/session/cookies.js b/keyserver/src/session/cookies.js
--- a/keyserver/src/session/cookies.js
+++ b/keyserver/src/session/cookies.js
@@ -842,8 +842,8 @@
   platformDetails: PlatformDetails,
 ): Promise<void> {
   if (
-    hasMinCodeVersion(platformDetails, 70) &&
-    !hasMinCodeVersion(viewer.platformDetails, 70)
+    hasMinCodeVersion(platformDetails, { native: 70 }) &&
+    !hasMinCodeVersion(viewer.platformDetails, { native: 70 })
   ) {
     await updateThreadMembers(viewer);
   }
diff --git a/keyserver/src/session/version.js b/keyserver/src/session/version.js
--- a/keyserver/src/session/version.js
+++ b/keyserver/src/session/version.js
@@ -10,7 +10,7 @@
   viewer: Viewer,
   platformDetails: ?PlatformDetails,
 ) {
-  if (hasMinCodeVersion(platformDetails, 31)) {
+  if (hasMinCodeVersion(platformDetails, { native: 31 })) {
     return;
   }
   const error = new ServerError('client_version_unsupported');
diff --git a/keyserver/src/socket/session-utils.js b/keyserver/src/socket/session-utils.js
--- a/keyserver/src/socket/session-utils.js
+++ b/keyserver/src/socket/session-utils.js
@@ -371,7 +371,9 @@
   status: StateCheckStatus,
   calendarQuery: CalendarQuery,
 ): Promise<StateCheckResult> {
-  const shouldCheckUserInfos = hasMinCodeVersion(viewer.platformDetails, 59);
+  const shouldCheckUserInfos = hasMinCodeVersion(viewer.platformDetails, {
+    native: 59,
+  });
 
   if (status.status === 'state_validated') {
     return { sessionUpdate: { lastValidated: Date.now() } };
diff --git a/keyserver/src/updaters/account-updaters.js b/keyserver/src/updaters/account-updaters.js
--- a/keyserver/src/updaters/account-updaters.js
+++ b/keyserver/src/updaters/account-updaters.js
@@ -192,7 +192,7 @@
     knownUserInfos,
   );
 
-  if (hasMinCodeVersion(viewer.platformDetails, 215)) {
+  if (hasMinCodeVersion(viewer.platformDetails, { native: 215 })) {
     const updateUserAvatarResponse: UpdateUserAvatarResponse = {
       updates,
     };
diff --git a/keyserver/src/updaters/thread-updaters.js b/keyserver/src/updaters/thread-updaters.js
--- a/keyserver/src/updaters/thread-updaters.js
+++ b/keyserver/src/updaters/thread-updaters.js
@@ -128,7 +128,7 @@
   };
   const newMessageInfos = await createMessages(viewer, [messageData]);
 
-  if (hasMinCodeVersion(viewer.platformDetails, 62)) {
+  if (hasMinCodeVersion(viewer.platformDetails, { native: 62 })) {
     return { updatesResult: { newUpdates: viewerUpdates }, newMessageInfos };
   }
 
@@ -218,7 +218,7 @@
     return await createMessages(viewer, [messageData]);
   })();
 
-  if (hasMinCodeVersion(viewer.platformDetails, 62)) {
+  if (hasMinCodeVersion(viewer.platformDetails, { native: 62 })) {
     return { updatesResult: { newUpdates: viewerUpdates }, newMessageInfos };
   }
 
@@ -252,7 +252,7 @@
   const threadInfo = fetchThreadResult.threadInfos[request.threadID];
 
   if (!viewerIsMember(threadInfo)) {
-    if (hasMinCodeVersion(viewer.platformDetails, 62)) {
+    if (hasMinCodeVersion(viewer.platformDetails, { native: 62 })) {
       return {
         updatesResult: { newUpdates: [] },
       };
@@ -304,7 +304,7 @@
   };
   await createMessages(viewer, [messageData]);
 
-  if (hasMinCodeVersion(viewer.platformDetails, 62)) {
+  if (hasMinCodeVersion(viewer.platformDetails, { native: 62 })) {
     return { updatesResult: { newUpdates: viewerUpdates } };
   }
 
@@ -788,7 +788,7 @@
     newMessageInfos = await createMessages(viewer, messageDatas);
   }
 
-  if (hasMinCodeVersion(viewer.platformDetails, 62)) {
+  if (hasMinCodeVersion(viewer.platformDetails, { native: 62 })) {
     return { updatesResult: { newUpdates: viewerUpdates }, newMessageInfos };
   }
 
@@ -826,8 +826,12 @@
   }
 
   // TODO: determine code version
-  const hasCodeVersionBelow87 = !hasMinCodeVersion(viewer.platformDetails, 87);
-  const hasCodeVersionBelow62 = !hasMinCodeVersion(viewer.platformDetails, 62);
+  const hasCodeVersionBelow87 = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 87,
+  });
+  const hasCodeVersionBelow62 = !hasMinCodeVersion(viewer.platformDetails, {
+    native: 62,
+  });
 
   const { calendarQuery } = request;
   if (isMember) {
diff --git a/keyserver/src/utils/validation-utils.js b/keyserver/src/utils/validation-utils.js
--- a/keyserver/src/utils/validation-utils.js
+++ b/keyserver/src/utils/validation-utils.js
@@ -37,7 +37,9 @@
   const convertedInput = checkInputValidator(inputValidator, input);
 
   if (
-    hasMinCodeVersion(viewer.platformDetails, FUTURE_CODE_VERSION) &&
+    hasMinCodeVersion(viewer.platformDetails, {
+      native: FUTURE_CODE_VERSION,
+    }) &&
     !isWebPlatform(viewer.platformDetails?.platform) &&
     convertToNewIDSchema
   ) {
@@ -69,7 +71,7 @@
   }
 
   if (
-    hasMinCodeVersion(platformDetails, FUTURE_CODE_VERSION) &&
+    hasMinCodeVersion(platformDetails, { native: FUTURE_CODE_VERSION }) &&
     !isWebPlatform(platformDetails?.platform) &&
     convertToNewIDSchema
   ) {
@@ -204,7 +206,7 @@
   if (!policies.length) {
     return;
   }
-  if (!hasMinCodeVersion(viewer.platformDetails, 181)) {
+  if (!hasMinCodeVersion(viewer.platformDetails, { native: 181 })) {
     return;
   }
 
diff --git a/lib/shared/messages/create-sidebar-message-spec.js b/lib/shared/messages/create-sidebar-message-spec.js
--- a/lib/shared/messages/create-sidebar-message-spec.js
+++ b/lib/shared/messages/create-sidebar-message-spec.js
@@ -162,7 +162,7 @@
     rawMessageInfo: RawCreateSidebarMessageInfo,
     platformDetails: ?PlatformDetails,
   ): RawCreateSidebarMessageInfo | RawUnsupportedMessageInfo {
-    if (hasMinCodeVersion(platformDetails, 75)) {
+    if (hasMinCodeVersion(platformDetails, { native: 75 })) {
       return rawMessageInfo;
     }
     const { id } = rawMessageInfo;
diff --git a/lib/shared/messages/edit-message-spec.js b/lib/shared/messages/edit-message-spec.js
--- a/lib/shared/messages/edit-message-spec.js
+++ b/lib/shared/messages/edit-message-spec.js
@@ -119,7 +119,7 @@
     rawMessageInfo: RawEditMessageInfo,
     platformDetails: ?PlatformDetails,
   ): RawEditMessageInfo | RawUnsupportedMessageInfo {
-    if (hasMinCodeVersion(platformDetails, 215)) {
+    if (hasMinCodeVersion(platformDetails, { native: 215 })) {
       return rawMessageInfo;
     }
     const { id } = rawMessageInfo;
diff --git a/lib/shared/messages/multimedia-message-spec.js b/lib/shared/messages/multimedia-message-spec.js
--- a/lib/shared/messages/multimedia-message-spec.js
+++ b/lib/shared/messages/multimedia-message-spec.js
@@ -224,14 +224,17 @@
     if (
       !containsBlobServiceMedia &&
       !containsEncryptedMedia &&
-      hasMinCodeVersion(platformDetails, 158)
+      hasMinCodeVersion(platformDetails, { native: 158 })
     ) {
       return rawMessageInfo;
     }
-    if (!containsBlobServiceMedia && hasMinCodeVersion(platformDetails, 205)) {
+    if (
+      !containsBlobServiceMedia &&
+      hasMinCodeVersion(platformDetails, { native: 205 })
+    ) {
       return rawMessageInfo;
     }
-    if (hasMinCodeVersion(platformDetails, FUTURE_CODE_VERSION)) {
+    if (hasMinCodeVersion(platformDetails, { native: FUTURE_CODE_VERSION })) {
       return rawMessageInfo;
     }
 
diff --git a/lib/shared/messages/reaction-message-spec.js b/lib/shared/messages/reaction-message-spec.js
--- a/lib/shared/messages/reaction-message-spec.js
+++ b/lib/shared/messages/reaction-message-spec.js
@@ -140,7 +140,7 @@
     rawMessageInfo: RawReactionMessageInfo,
     platformDetails: ?PlatformDetails,
   ): RawReactionMessageInfo | RawUnsupportedMessageInfo {
-    if (hasMinCodeVersion(platformDetails, 167)) {
+    if (hasMinCodeVersion(platformDetails, { native: 167 })) {
       return rawMessageInfo;
     }
     const { id } = rawMessageInfo;
diff --git a/lib/shared/messages/sidebar-source-message-spec.js b/lib/shared/messages/sidebar-source-message-spec.js
--- a/lib/shared/messages/sidebar-source-message-spec.js
+++ b/lib/shared/messages/sidebar-source-message-spec.js
@@ -135,7 +135,7 @@
     platformDetails: ?PlatformDetails,
   ): RawSidebarSourceMessageInfo | RawUnsupportedMessageInfo {
     if (
-      hasMinCodeVersion(platformDetails, 75) &&
+      hasMinCodeVersion(platformDetails, { native: 75 }) &&
       rawMessageInfo.sourceMessage
     ) {
       return rawMessageInfo;
diff --git a/lib/shared/messages/toggle-pin-message-spec.js b/lib/shared/messages/toggle-pin-message-spec.js
--- a/lib/shared/messages/toggle-pin-message-spec.js
+++ b/lib/shared/messages/toggle-pin-message-spec.js
@@ -132,7 +132,7 @@
     rawMessageInfo: RawTogglePinMessageInfo,
     platformDetails: ?PlatformDetails,
   ): RawTogglePinMessageInfo | RawUnsupportedMessageInfo {
-    if (hasMinCodeVersion(platformDetails, 209)) {
+    if (hasMinCodeVersion(platformDetails, { native: 209 })) {
       return rawMessageInfo;
     }
     const { id } = rawMessageInfo;
diff --git a/lib/shared/messages/update-relationship-message-spec.js b/lib/shared/messages/update-relationship-message-spec.js
--- a/lib/shared/messages/update-relationship-message-spec.js
+++ b/lib/shared/messages/update-relationship-message-spec.js
@@ -132,7 +132,7 @@
     rawMessageInfo: RawUpdateRelationshipMessageInfo,
     platformDetails: ?PlatformDetails,
   ): RawUpdateRelationshipMessageInfo | RawUnsupportedMessageInfo {
-    if (hasMinCodeVersion(platformDetails, 71)) {
+    if (hasMinCodeVersion(platformDetails, { native: 71 })) {
       return rawMessageInfo;
     }
     const { id } = rawMessageInfo;
diff --git a/lib/shared/version-utils.js b/lib/shared/version-utils.js
--- a/lib/shared/version-utils.js
+++ b/lib/shared/version-utils.js
@@ -10,15 +10,23 @@
 
 function hasMinCodeVersion(
   platformDetails: ?PlatformDetails,
-  minCodeVersion: number,
+  minCodeVersion: $Shape<{ +native: number, +web: number }>,
 ): boolean {
-  if (!platformDetails || isWebPlatform(platformDetails.platform)) {
+  if (!platformDetails) {
     return true;
   }
   const { codeVersion } = platformDetails;
-  if (!codeVersion || codeVersion < minCodeVersion) {
+  const minVersion = isWebPlatform(platformDetails.platform)
+    ? minCodeVersion.web
+    : minCodeVersion.native;
+
+  if (!minVersion) {
+    return true;
+  }
+  if (!codeVersion || codeVersion < minVersion) {
     return false;
   }
+
   return true;
 }