React & Expo: A journey of uploading raw image data to S3
Explore how to upload raw image data to Amazon S3 in a React Native Expo app. This guide walks through handling image selection, converting data for upload, and securely sending files to S3, with practical code examples.
Our journey beings when using the React ImagePicker, where the user of our application can select the image and then we receive a result that contains the URI of our associated image.
We need to take this URI and ultimately upload it to Amazon S3 through a signed URL. Unfortunately, we cannot just simply use the URI like we would with FormData like we would if we were uploading to an API because this is a PUT request with the data contained directly.
Ok, so let us get the contents of the image and all we have is the URI. Why can I not get the image as something more useful? Let’s break out the FileReader to get this as an ArrayBuffer. Wait…! You mean to tell me that Expo and React do not contain readAsArrayBuffer?!
Everything is Falling Apart
Maybe there is another path, so we start searching for Upload Image to S3 from Expo (or React). You will run into examples where people use a custom backend (don’t do this). Back to looking for a way to read the image as an array buffer. Maybe there is a readAsArrayBuffer polyfill or an NPM module that will handle this situation... If you are using React, you will likely have found that you can use RNFetchBlob which will work for you. Although, those of you on Expo have struck out. Maybe it’s time to eject the app for this fundamental requirement… However, we cannot believe there is not a different way.
The Easy Way Forward
Fortunately, there is an easy solution. You do not need to require a new NPM module, you don’t need readAsArrayBuffer, all of the tools are there for you and quite literally, it was far too easy and obvious. What you might not know is that you can set the body of a fetch request to a File reference. We can actually create one of these directly from a blob.
Conclusion
Sometimes the answers are right in front of us. In this case, we knew we likely needed to pass an array buffer. Unfortunately, instead of looking for another solution we dug in and went too deep. When this happens, generally it is time to look for a different way and a different way proved to be the better, more condense and fool proof solution.
Related posts
The best ideas don't wait. Let's talk & make it happen.
© Spark Labs 2025. All rights reserved.