Several years ago, our mobile team began building a native mobile app. It was originally designed as fully native and entirely separate from our existing mobile frontend. One of the first challenges we worked on was providing a unified authentication system with a magic email link that would work seamlessly across all of our forums. We wanted to make it easier for visitors to access all of our online communities. This meant figuring out the best way to sync data across old and new systems that were serving existing vs. newly created content. We also had to think about how to structure this to provide useful access patterns for our mobile app and future web updates.
I initially worked on a graph-based API written in Go that was fast and robust enough to handle requests made by millions of visitors from over 1,000 sites. Most of my prior experiences were in backend development, so the tasks were familiar: designing endpoints, writing queries, and constructing containers.
Last year, however, we made a critical change to get to market faster and focus our consumer value proposition. Rather than try to achieve full parity with our web app, we decided to prioritize native app development on specific features that would meet our users’ most important needs, such as notifications and rich content creation.
The strategy change also meant a change in my role. I transitioned from mostly backend development to frontend development. Prior to Fora, I’d done some frontend work with React Redux and Ionic, but I hadn’t had much exposure to building out a complete mobile frontend experience. Today, I am a Flutter developer, building out our new experiences and integrating the UI with our existing endpoints.
This style of development was both new and uncomfortable. Previously, I’d build each layer of the application backend (data → business → adapter → GraphQL API), each component relying on each other at key points but mostly independent. Now, with Flutter, I use the BLoC (Business Logic Components) pattern to control the flow of data in our app. BLoC revolves around mostly stateless UI components which rebuild based on changes to the state of the Blocs and Cubits they listen to. The state is updated by events and methods triggered via interactions and updates received by our app.
This is similar to React Redux but has its own take on how to manage an application. Blocs respond to events being fired off within the application’s logic, mainly via user interactions. Cubits can do the same without the notion of events, instead opting to use direct methods on the Cubit class. Blocs and Cubits interact with our backend services via a repository layer and share data via reactive repositories to keep multiple domains of the app in sync. As the events come in, methods get called, and repositories receive updates. The app UI then updates as it detects changes in the state, triggering events via listeners and rebuilding UI components via builders defined throughout Flutter’s widget tree. It’s a much more dynamic experience compared to building out a GraphQL API.
The transition from backend to frontend was initially difficult. It was easy to get lost when updates unexpectedly changed components. But after a while, building the app has become more like building my own tool. I’ve become more familiar with each aspect of the system, changes seem more controlled, and connecting the dots has become closer to second nature. I also had to mentally shift how I think about writing code. Without my team, I wouldn’t have been able to complete the switch as smoothly or with the same depth of knowledge. Switching from backend to frontend has given me valuable experience and a greater understanding of the whole picture.
Grow with us
If you value learning and growth as much as we do, join us!Join us now