diff --git a/native/.flowconfig b/native/.flowconfig
--- a/native/.flowconfig
+++ b/native/.flowconfig
@@ -40,6 +40,7 @@
 format.bracket_spacing=false
 
 module.file_ext=.js
+module.file_ext=.mjs
 module.file_ext=.json
 module.file_ext=.ios.js
 module.file_ext=.android.js
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.h
@@ -30,6 +30,7 @@
 namespace jsi = facebook::jsi;
 
 class CommCoreModule : public facebook::react::CommCoreModuleSchemaCxxSpecJSI {
+  // Version defined in native/version.mjs and updated by update-version script
   const int codeVersion{472};
   std::unique_ptr<WorkerThread> cryptoThread;
 
diff --git a/native/package.json b/native/package.json
--- a/native/package.json
+++ b/native/package.json
@@ -20,7 +20,8 @@
     "codegen-jsi": "flow && babel codegen/src/ -d codegen/dist/ && node codegen/dist",
     "react-native": "PATH=/usr/bin:/bin:\"$PATH\" react-native",
     "expo": "PATH=/usr/bin:/bin:\"$PATH\" expo",
-    "xcodebuild": "cd ios && PATH=/usr/bin:/bin:\"$PATH\" xcodebuild"
+    "xcodebuild": "cd ios && PATH=/usr/bin:/bin:\"$PATH\" xcodebuild",
+    "update-version": "node scripts/update-mobile-version.mjs"
   },
   "devDependencies": {
     "@babel/cli": "^7.23.4",
diff --git a/native/redux/persist.js b/native/redux/persist.js
--- a/native/redux/persist.js
+++ b/native/redux/persist.js
@@ -157,6 +157,7 @@
 import { defaultDeviceCameraInfo } from '../types/camera.js';
 import { isTaskCancelledError } from '../utils/error-handling.js';
 import { defaultURLPrefix } from '../utils/url-utils.js';
+import { codeVersion } from '../version.mjs';
 
 const legacyMigrations = {
   [1]: (state: AppState) => ({
@@ -1547,8 +1548,6 @@
   timeout: ((__DEV__ ? 0 : 30000): number | void),
 };
 
-const codeVersion: number = commCoreModule.getCodeVersion();
-
 // This local exists to avoid a circular dependency where redux-setup needs to
 // import all the navigation and screen stuff, but some of those screens want to
 // access the persistor to purge its state.
diff --git a/native/scripts/update-mobile-version.mjs b/native/scripts/update-mobile-version.mjs
new file mode 100755
--- /dev/null
+++ b/native/scripts/update-mobile-version.mjs
@@ -0,0 +1,147 @@
+// @flow
+
+/**
+ * Script to update version in all mobile build files
+ * from the source of truth in native/version.mjs.
+ */
+
+import fs from 'fs';
+import invariant from 'invariant';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+import { codeVersion, codeVersionName } from '../version.mjs';
+
+// Get directory name in ESM
+const { url } = import.meta;
+invariant(url, 'URL should be set');
+const filename = fileURLToPath(url);
+const dirname = path.dirname(filename);
+
+// Paths
+const nativeDir = path.resolve(dirname, '..');
+const headerPath = path.join(
+  nativeDir,
+  'cpp/CommonCpp/NativeModules/CommCoreModule.h',
+);
+const androidGradlePath = path.join(nativeDir, 'android/app/build.gradle');
+const iosProjectPath = path.join(
+  nativeDir,
+  'ios/Comm.xcodeproj/project.pbxproj',
+);
+const iosInfoDebugPath = path.join(nativeDir, 'ios/Comm/Info.debug.plist');
+const iosInfoReleasePath = path.join(nativeDir, 'ios/Comm/Info.release.plist');
+
+// Update CommCoreModule.h
+function updateCommCoreModule() {
+  let content = fs.readFileSync(headerPath, 'utf8');
+
+  // Replace codeVersion value
+  content = content.replace(
+    /const int codeVersion\{[0-9]+\};/,
+    `const int codeVersion{${codeVersion}};`,
+  );
+
+  fs.writeFileSync(headerPath, content);
+  console.log(`Updated codeVersion in CommCoreModule.h to ${codeVersion}`);
+}
+
+// Update Android build.gradle
+function updateAndroidGradle() {
+  let content = fs.readFileSync(androidGradlePath, 'utf8');
+
+  // Replace versionCode
+  content = content.replace(/versionCode [0-9]+/, `versionCode ${codeVersion}`);
+
+  // Replace versionName
+  content = content.replace(
+    /versionName '[^']+'/,
+    `versionName '${codeVersionName}'`,
+  );
+
+  fs.writeFileSync(androidGradlePath, content);
+  console.log(`Updated Android version to ${codeVersionName} (${codeVersion})`);
+}
+
+// Update iOS project.pbxproj
+function updateIOSProject() {
+  let content = fs.readFileSync(iosProjectPath, 'utf8');
+
+  // Replace CURRENT_PROJECT_VERSION
+  content = content.replace(
+    /CURRENT_PROJECT_VERSION = [0-9]+;/g,
+    `CURRENT_PROJECT_VERSION = ${codeVersion};`,
+  );
+
+  // Replace MARKETING_VERSION
+  content = content.replace(
+    /MARKETING_VERSION = [^;]+;/g,
+    `MARKETING_VERSION = ${codeVersionName};`,
+  );
+
+  fs.writeFileSync(iosProjectPath, content);
+  console.log(`Updated iOS project version to ${codeVersionName}`);
+}
+
+// Update iOS Info.plist files
+function updateIOSInfoPlists() {
+  // Update Info.debug.plist
+  let debugContent = fs.readFileSync(iosInfoDebugPath, 'utf8');
+
+  // Replace bundle short version string
+  const shortVersionRegex =
+    /<key>CFBundleShortVersionString<\/key>\s*<string>[^<]+<\/string>/;
+  const shortVersionReplacement =
+    `<key>CFBundleShortVersionString</key>\n\t` +
+    `<string>${codeVersionName}</string>`;
+  debugContent = debugContent.replace(
+    shortVersionRegex,
+    shortVersionReplacement,
+  );
+
+  // Replace bundle version
+  const bundleVersionRegex =
+    /<key>CFBundleVersion<\/key>\s*<string>[^<]+<\/string>/;
+  const bundleVersionReplacement = `<key>CFBundleVersion</key>\n\t<string>${codeVersion}</string>`;
+  debugContent = debugContent.replace(
+    bundleVersionRegex,
+    bundleVersionReplacement,
+  );
+
+  fs.writeFileSync(iosInfoDebugPath, debugContent);
+
+  // Update Info.release.plist
+  let releaseContent = fs.readFileSync(iosInfoReleasePath, 'utf8');
+
+  // Replace bundle short version string
+  releaseContent = releaseContent.replace(
+    shortVersionRegex,
+    shortVersionReplacement,
+  );
+
+  // Replace bundle version
+  releaseContent = releaseContent.replace(
+    bundleVersionRegex,
+    bundleVersionReplacement,
+  );
+
+  fs.writeFileSync(iosInfoReleasePath, releaseContent);
+
+  console.log(`Updated iOS Info.plist files to ${codeVersionName}`);
+}
+
+// Run all updates
+function updateAll() {
+  try {
+    updateCommCoreModule();
+    updateAndroidGradle();
+    updateIOSProject();
+    updateIOSInfoPlists();
+    console.log('All version files updated successfully!');
+  } catch (error) {
+    console.error('Error updating version files:', error);
+    process.exit(1);
+  }
+}
+
+updateAll();
diff --git a/native/version.mjs b/native/version.mjs
new file mode 100644
--- /dev/null
+++ b/native/version.mjs
@@ -0,0 +1,4 @@
+// @flow
+
+export const codeVersion = 472;
+export const codeVersionName = '1.0.472';