diff --git a/native/cpp/CommonCpp/NativeModules/CommUtilsModule.h b/native/cpp/CommonCpp/NativeModules/CommUtilsModule.h
--- a/native/cpp/CommonCpp/NativeModules/CommUtilsModule.h
+++ b/native/cpp/CommonCpp/NativeModules/CommUtilsModule.h
@@ -32,6 +32,10 @@
   virtual jsi::Object
   base64DecodeBuffer(jsi::Runtime &rt, jsi::String base64) override;
   virtual jsi::String sha256(jsi::Runtime &rt, jsi::Object data) override;
+  virtual jsi::String
+  decodeUTF8ArrayBufferToString(jsi::Runtime &rt, jsi::Object data) override;
+  virtual jsi::Object
+  encodeStringToUTF8ArrayBuffer(jsi::Runtime &rt, jsi::String str) override;
 
 public:
   CommUtilsModule(std::shared_ptr<facebook::react::CallInvoker> jsInvoker);
diff --git a/native/cpp/CommonCpp/NativeModules/CommUtilsModule.cpp b/native/cpp/CommonCpp/NativeModules/CommUtilsModule.cpp
--- a/native/cpp/CommonCpp/NativeModules/CommUtilsModule.cpp
+++ b/native/cpp/CommonCpp/NativeModules/CommUtilsModule.cpp
@@ -150,4 +150,42 @@
   return jsi::String::createFromUtf8(rt, sha256String);
 }
 
+jsi::String CommUtilsModule::decodeUTF8ArrayBufferToString(
+    jsi::Runtime &rt,
+    jsi::Object data) {
+  auto arrayBuffer = data.getArrayBuffer(rt);
+  auto dataPtr = arrayBuffer.data(rt);
+  auto size = arrayBuffer.size(rt);
+
+  auto bytes = std::vector<uint8_t>{dataPtr, dataPtr + size};
+  auto str = std::string(bytes.begin(), bytes.end());
+  jsi::String jsiStr = jsi::String::createFromUtf8(rt, str);
+
+  // createFromUtf8() results are undefined if
+  // str contains invalid code points.
+  auto strAfterConversion = jsiStr.utf8(rt);
+  if (str != strAfterConversion) {
+    throw jsi::JSError(rt, "Invalid UTF-8 ArrayBuffer");
+  }
+
+  return jsiStr;
+}
+
+jsi::Object CommUtilsModule::encodeStringToUTF8ArrayBuffer(
+    jsi::Runtime &rt,
+    jsi::String inputStr) {
+  auto str = inputStr.utf8(rt);
+  auto bytes = std::vector<uint8_t>(str.begin(), str.end());
+  auto size = bytes.size();
+
+  auto arrayBuffer = rt.global()
+                         .getPropertyAsFunction(rt, "ArrayBuffer")
+                         .callAsConstructor(rt, {static_cast<double>(size)})
+                         .asObject(rt)
+                         .getArrayBuffer(rt);
+
+  memcpy(arrayBuffer.data(rt), bytes.data(), size);
+  return std::move(arrayBuffer);
+}
+
 } // namespace comm
diff --git a/native/cpp/CommonCpp/_generated/utilsJSI-generated.cpp b/native/cpp/CommonCpp/_generated/utilsJSI-generated.cpp
--- a/native/cpp/CommonCpp/_generated/utilsJSI-generated.cpp
+++ b/native/cpp/CommonCpp/_generated/utilsJSI-generated.cpp
@@ -27,6 +27,12 @@
 static jsi::Value __hostFunction_CommUtilsModuleSchemaCxxSpecJSI_sha256(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
   return static_cast<CommUtilsModuleSchemaCxxSpecJSI *>(&turboModule)->sha256(rt, args[0].asObject(rt));
 }
+static jsi::Value __hostFunction_CommUtilsModuleSchemaCxxSpecJSI_decodeUTF8ArrayBufferToString(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
+  return static_cast<CommUtilsModuleSchemaCxxSpecJSI *>(&turboModule)->decodeUTF8ArrayBufferToString(rt, args[0].asObject(rt));
+}
+static jsi::Value __hostFunction_CommUtilsModuleSchemaCxxSpecJSI_encodeStringToUTF8ArrayBuffer(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
+  return static_cast<CommUtilsModuleSchemaCxxSpecJSI *>(&turboModule)->encodeStringToUTF8ArrayBuffer(rt, args[0].asString(rt));
+}
 
 CommUtilsModuleSchemaCxxSpecJSI::CommUtilsModuleSchemaCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
   : TurboModule("CommUtilsTurboModule", jsInvoker) {
@@ -35,6 +41,8 @@
   methodMap_["base64EncodeBuffer"] = MethodMetadata {1, __hostFunction_CommUtilsModuleSchemaCxxSpecJSI_base64EncodeBuffer};
   methodMap_["base64DecodeBuffer"] = MethodMetadata {1, __hostFunction_CommUtilsModuleSchemaCxxSpecJSI_base64DecodeBuffer};
   methodMap_["sha256"] = MethodMetadata {1, __hostFunction_CommUtilsModuleSchemaCxxSpecJSI_sha256};
+  methodMap_["decodeUTF8ArrayBufferToString"] = MethodMetadata {1, __hostFunction_CommUtilsModuleSchemaCxxSpecJSI_decodeUTF8ArrayBufferToString};
+  methodMap_["encodeStringToUTF8ArrayBuffer"] = MethodMetadata {1, __hostFunction_CommUtilsModuleSchemaCxxSpecJSI_encodeStringToUTF8ArrayBuffer};
 }
 
 
diff --git a/native/cpp/CommonCpp/_generated/utilsJSI.h b/native/cpp/CommonCpp/_generated/utilsJSI.h
--- a/native/cpp/CommonCpp/_generated/utilsJSI.h
+++ b/native/cpp/CommonCpp/_generated/utilsJSI.h
@@ -25,6 +25,8 @@
   virtual jsi::String base64EncodeBuffer(jsi::Runtime &rt, jsi::Object data) = 0;
   virtual jsi::Object base64DecodeBuffer(jsi::Runtime &rt, jsi::String base64) = 0;
   virtual jsi::String sha256(jsi::Runtime &rt, jsi::Object data) = 0;
+  virtual jsi::String decodeUTF8ArrayBufferToString(jsi::Runtime &rt, jsi::Object data) = 0;
+  virtual jsi::Object encodeStringToUTF8ArrayBuffer(jsi::Runtime &rt, jsi::String str) = 0;
 
 };
 
@@ -86,6 +88,22 @@
       return bridging::callFromJs<jsi::String>(
           rt, &T::sha256, jsInvoker_, instance_, std::move(data));
     }
+    jsi::String decodeUTF8ArrayBufferToString(jsi::Runtime &rt, jsi::Object data) override {
+      static_assert(
+          bridging::getParameterCount(&T::decodeUTF8ArrayBufferToString) == 2,
+          "Expected decodeUTF8ArrayBufferToString(...) to have 2 parameters");
+
+      return bridging::callFromJs<jsi::String>(
+          rt, &T::decodeUTF8ArrayBufferToString, jsInvoker_, instance_, std::move(data));
+    }
+    jsi::Object encodeStringToUTF8ArrayBuffer(jsi::Runtime &rt, jsi::String str) override {
+      static_assert(
+          bridging::getParameterCount(&T::encodeStringToUTF8ArrayBuffer) == 2,
+          "Expected encodeStringToUTF8ArrayBuffer(...) to have 2 parameters");
+
+      return bridging::callFromJs<jsi::Object>(
+          rt, &T::encodeStringToUTF8ArrayBuffer, jsInvoker_, instance_, std::move(str));
+    }
 
   private:
     T *instance_;
diff --git a/native/schema/CommUtilsModuleSchema.js b/native/schema/CommUtilsModuleSchema.js
--- a/native/schema/CommUtilsModuleSchema.js
+++ b/native/schema/CommUtilsModuleSchema.js
@@ -15,6 +15,9 @@
   +base64DecodeBuffer: (base64: string) => JSIArrayBuffer;
   // crypto utils
   +sha256: (data: JSIArrayBuffer) => string;
+  // encoding utils
+  +decodeUTF8ArrayBufferToString: (data: JSIArrayBuffer) => string;
+  +encodeStringToUTF8ArrayBuffer: (str: string) => JSIArrayBuffer;
 }
 
 // for public interface, we use the correct types
@@ -24,6 +27,8 @@
   +base64EncodeBuffer: (data: ArrayBuffer) => string;
   +base64DecodeBuffer: (base64: string) => ArrayBuffer;
   +sha256: (data: ArrayBuffer) => string;
+  +decodeUTF8ArrayBufferToString: (data: ArrayBuffer) => string;
+  +encodeStringToUTF8ArrayBuffer: (str: string) => ArrayBuffer;
 }
 
 export default (TurboModuleRegistry.getEnforcing<Spec>(