Prototyping a social media app cover

Our learnings from prototyping a mobile social media app

Our friends over at Oversight Studio came to us with one task: to prototype a mobile social media app as fast as possible. Having never done mobile development before we jumped at the opportunity and the goal was to make as many mistakes as possible so as to learn from them in the real project that followed by developing one vertical slice of the app.

If you've done mobile development before you know where this is going, React Native; or a form of it at least.

The criteria was simple:

  • Determine the tech stack to be used
  • Build the base structure and infrastructure that a brand new dev team can just take and focus on features
  • Find potential pitfalls before they become blockers

The tech stack

The short of it yeah, React Native. We immediately ruled out Swift and Kotlin or other native alternatives due to the difficulty in assembling a dev team to take on two different codebases slowing down the initial build. Tauri was not yet mobile ready and Electron was not going to be any simpler with potential performance and high RAM usage issues. You of course have many more options to pick from such as Flutter or Ionic, and NativeScript was also a possibility, but here popularity won it for us as we assumed we'd encounter less problems.

React Native (RN) comes in many forms and for us it was a no-brainer as it would make hiring devs much easier due to the popularity of the package. You can use RN directly however we chose to use Expo instead as it's well supported and can handle a lot of features out of the box for you.

Our backend was initially Supabase, though eventually we settled on a custom Nestjs API.

Getting humbled.

If you've never done native development before and you're coming straight from the world of web, you will be very quickly humbled by mobile as well as grow a new-found gratefulness for what we have when it comes to the power of CSS. Now some of these sound obvious really but they're worth mentioning to highlight just how easy we have it.

There's no styling inheritance. You have to really wrap your head around this but if you set for example a font size or colour on a parent, none of the children will inherit these styles, they have to be explicitly stated.

No URL. Kind of, you have the concept of screens with a name but there's no inherent URL structure even internal that you could leverage; sounds obvious but it does force you to change how you think about your app.

React Native is not stable. This one is the most important and least talked about aspects of RN. You have to accept that it's not in fact anywhere close as stable as React itself, as we encountered several core bugs around basic functionality. Luckily the community here is one of the best, with tons of tutorials, maintained packages to solve weird and niche issues and an active community to help you along.

Backend

As we mentioned, Supabase was our initial choice here for a backend, just working and providing useful functionality out of the box is their speciality. However the JS SDK at the time was having issues with React Native, and this is a common theme as we find out. It had quite a few open issues around authentication which massively stifled our progress, issues that in the end would take weeks to resolve.

Due to expertise on the team we then settled for Nest.js which as a framework would allow the team to quickly fulfil all the requirements around support all kinds of authentication methods, data types and integration with various third party APIs for mapping, ID verification, payments and more.

The other option was to fully leverage Expo's product offering but vendor lock-in here was a big concern.

Third party services

There were quite a few integrations we needed to establish early on, for example a mapping and location API, a search API, analytics and so on. We'll skip the introductions and jump to our solutions:

PostHog is open source and integrates with BigQuery, to allow the analytics team to handle the data however they need to. We settled with Google Cloud services due to the feature sets and the free credits that would keep the project going for a while before needing to pay anything. And Meilisearch is just awesome, an open source, feature rich and super fast search indexer.

Frontend

Nativewind worked out of the box for us, more or less and most features were surprisingly supported. Animations were not working and that's where the Reanimated library comes in to help out.

The main attraction to developing an app instead of just supporting a mobile website is the integration and the feel of the app and this is something that can be quite tricky to get right with RN, it's not enough to just animate a slide out, it needs to respond in real time to drag gestures and have momentum and that's why you need to use the React Native Gesture Handler library in tandem.

The other alternative we explored was re-using individual components shared by the community but the shortcoming here was that you'd find yourself lacking particular components which you would have to build yourself anyway, so might as well assemble the core utilities and build up a small library of components you can re-use.

For navigation, you guessed it, we used React Navigation, a library specifically made to help your handle routing via all the common methods such as drawers, it's a fantastic library with very good documentation and examples.

Wondering what RN code looks like? Here's an example of a button, simplified greatly, using Pressable component as the DOM doesn't exist for mobile, and accessibility functions differently too:

1import { Pressable, PressableProps } from "react-native";
2
3function Button({title}) {
4 return (
5 <Pressable>
6 <Text styles="text-center font-inter-medium text-white pl-4">{title}</Text>
7 </Pressable>
8 );
9}
10
11export default Button;
typescript

What we would do differently?

Where to begin. We'd look at Expo's offerings with a deeper look and see if we can leverage at least some parts of it in a way that fits the business needs as it might've saved us a lot of time. Build fast, scale later.

Looking for a flexible and supported UI library before the design stage of the app would've greatly helped in removing barriers.

For the backend, next time we would be able to leverage Payload instead which will take care of all of our needs around authentication, content and admin panel.

In terms of speeding up the process of learnings, perhaps looking at some well regarded project templates would help a lot, something to keep in mind for trying out Tauri next, just so you don't have to go through the steps of figuring out small architecture details yourself such as folder structures, component re-use and setup.

A critical point for next time is defining clear metrics for everything else we care about when it comes to software which is performance and accessibility. How big is the resulting app, does it function well on slower devices, can we improve the rendering performance of animation or data heavy screens; while also ensuring we have a set of guidelines to present the developers around accessibility something we made sure not to forget and perhaps one to write up about in more depth in another article.

Hell yes, we'd do it again!

This project was very exciting for us and it allowed us to apply our existing knowledge and expertise in a very different context. Next time we come across the opportunity to work in the native software space we will be that much better.

If you're thinking about going the RN route, then please do and don't let this article dissuade you, the tech stack we went with was solid and fulfilled all of our needs, and you can just learn from our short-comings and skip straight to the important parts! Of course this article is going to age very poorly very quickly as tech always moves faster than we have time to reflect, as we speak Tauri is rapidly adding mobile support, React Native is fixing its core issues and even for mobile browsers the available APIs are constantly growing further blurring the line between web and native.

Give us a follow on Twitter if you want to keep up with our developments, we promise it's worth it!