Building software in a fast-paced environment means making trade-offs between speed and structure. But when does necessary speed cross the line into counterproductive chaos? In this article, We’ll share honest insights from a real project we delivered at Fabres – rebuilding the mobile app for our client, NAF – one of Norway’s top 5 most trusted brands with over 500,000 members, and reveal what really happens behind the scenes in a modern software house when deadlines are tight and priorities shift. This isn’t a polished success story. It’s a transparent look at the process and technical mistakes we made, why they happened, their real business consequences, and most importantly – the specific lessons we learned that you can apply to your own projects.
Section 1: the startup velocity trap
What we did
We approached this enterprise project with pure startup methodology: no formal sprints, loose Kanban, “live design” workshops with minimal documentation. Priorities shifted frequently as we discovered integration complexities with NAF’s existing systems.
For the first few months, this approach was our advantage. We moved incredibly fast.
When it became a problem

Around production launch in September, the symptoms became impossible to ignore:
- No decision documentation meant we couldn’t reconstruct why certain choices were made
- Constantly changing priorities created team confusion and duplicated effort
- Figma became a graveyard of abandoned design iterations, making consistency impossible
- No retrospectives meant we detected these problems too late
The chaos persists today in some areas. When we need to analyze historical decisions, it’s practically impossible.
What we should have done
- Implement lightweight decision logging from day one – capture the “what” and “why”, as well as the alternative options considered and the reasons they were not selected
- Hold bi-weekly retrospectives – an hour every two weeks would have surfaced chaos while manageable
- Recognize when velocity becomes chaos – we missed the inflection point
The irony: proper lightweight documentation would have made us faster, not slower.

Section 2: the technical debt we’re still paying for
Mistake 1: no forced update mechanism
We implemented OTA (over-the-air) updates with Expo framework, which proved to be an extremely convenient solution – in most cases, it allowed us to update the app for users almost seamlessly. However, some changes require releasing a new version through the stores (Google Play, App Store), and for those updates, we did not implement a mechanism to force users to move to the latest version.
The cost: we had to maintain old API versions for months, because some users continued using outdated app versions. Breaking changes couldn’t be applied without risking user trust. Integration with internal systems lacking API versioning required extra compatibility code. A forced update mechanism would have avoided this.
Real impact: Cannot decommission legacy systems without breaking service for non-updated users. Security vulnerabilities in old versions that we can’t force users away from.
Mistake 2: no feature flag infrastructure
We started with a simple feature flag system: only hardcoded internal testers had access. This worked initially, but as functionality like the Messaging Center grew and the tester group expanded, manual management became cumbersome. We couldn’t roll out features gradually, which meant thorough testing had to be completed before release, significantly extending the overall timeline.
The cost: Perfect synchronization required between frontend and backend. Our Messaging Center feature (in-app messages and push notifications) required:
- Build UI in app
- Wait for backend API and services, that are quite complex
- Deploy backend services and test multiple scenarios
- Submit to App Store and Google Play
- Wait 1-2 days for approvals
Feature flags allowed us to work in parallel and roll out changes gradually. However, access was hardcoded in the app, so adding new stakeholders required code changes and new test builds – creating significant and avoidable overhead.
Mistake 3: no version monitoring
We didn’t include current app version in the data we store in our monitoring solution.
The cost: Without logging app versions in our backend monitoring, we often encountered errors in alerts but had no way of knowing which app version caused them. Reproducing and debugging such issues was extremely difficult, as we couldn’t be sure we were testing the correct version. Eventually, we implemented a simple solution: the app started sending its version in a special HTTP header with every API request, which was then recorded in our monitoring system. However, since we initially lacked a forced update mechanism, it took months for this change to fully propagate and for all requests to include version information.
Mistake 4: misconfigured OTA update policies
Despite our team’s Expo experience, we misconfigured policies — matching Expo framework versions rather than app versions, preventing native code changes within the same Expo version.
The cost: We lost the ability to use OTA updates for a certain class of changes, reducing some of the convenience Expo provides, even though OTA was only one of several factors in our choice of the framework
Mistake 5: no user communication mechanism
No in-app notification or announcement system.
The cost: During one of several unexpected backend issues affecting roadside assistance, caused by a third-party system our platform integrates with, we had no way to inform users in-app. We received 200+ support tickets from users who thought the app was completely broken. A simple banner would have prevented most tickets.

Section 3: why these mistakes are so common
The MVP mindset trap
The entire MVP concept encourages cutting scope aggressively. But there’s a critical difference between cutting features and cutting infrastructure. Feature flags aren’t a feature – they’re infrastructure that makes feature development faster and safer.
The trap: “we’ll add that later.” But by the time you need it, you already have users on versions that don’t include it. You can’t retroactively add forced updates to version 1.0.
The documentation deferral
“We’ll document this later” is the most expensive lie in software development. Later never comes because context evaporates, new features seem more urgent, and the pain is distributed rather than acute.
Section 4: the framework advantage – why we still chose expo
Despite misconfiguring OTA updates, choosing Expo was still right. Traditional app updates require App Store submission and 1-3 day review. With OTA: push the update to a third-party service like Expo, and the app downloads it directly – bypassing the App Store and Google Play update process.
This speed difference is transformative for hotfixes, iteration velocity, and user experience. OTA updates minimize version fragmentation, and combined with forced updates for store releases, they ensure users quickly move to the latest version, giving us maintenance experience similar to web apps. On top of that, Expo offers other advantages: fast project setup, faster development without touching native code in most cases, and built-in update management.
Recommendation: For any app, we now consider OTA update capability a fundamental requirement, not a nice-to-have.
Section 5: The infrastructure checklist- what every mvp needs
Based on our experience, here’s what we now consider non-negotiable for any mobile app with a backend:
- Forced update mechanism (critical)
Implementation: On app launch, the current version is checked against backend-configured minimum required and minimum suggested versions. If the version is below the minimum suggested, the user is informed but can continue using the app. If it’s below the minimum required, a full-screen update prompt is shown, and the app cannot be used until updated. This approach provides flexibility – encouraging updates when suggested, while enforcing them when backward compatibility cannot be maintained.
Cost if skipped: Indefinite maintenance of legacy backends, inability to migrate infrastructure, compounding technical debt.
- Feature flags (critical)
Requirements: Remote control (toggle without rebuild), user targeting (specific IDs or percentages), environment awareness, flag management UI for non-developers.
Usage pattern: Ship features disabled, enable for internal testers, roll out to 10% of users, then 100% or rollback.
Cost if skipped: Cannot test features in production, must synchronize all deployments, extended time-to-market.
- Version monitoring (critical)
Implementation: Add X-App-Version header to all API requests, log with backend operations, create version distribution dashboard.
Cost if skipped: Extended debugging time, inability to make data-driven deprecation decisions.
- User communication system (high priority)
Minimum: Backend-controlled banner system displaying messages across screens, dismissible vs. persistent options, optional call-to-action button.
Cost if skipped: Poor incident experience, support ticket floods, missed marketing opportunities.
Section 6: how to apply these lessons
If you’re starting a new project
- Choose framework with OTA capability
- Set up infrastructure checklist (budget 1 week)
- Establish documentation minimums before first feature
- Test framework configuration thoroughly
Timeline adjustment: Add 1 week to MVP estimate for infrastructure. This makes everything else faster.
If you’re mid-development
- Start with app version monitoring immediately
- Add feature flags for the next feature and implement a mechanism for in-app communication with users
- Hold one documentation retrospective to review processes, identify improvements, and define next steps.
- Implement suggested and forced updates as soon as possible – the earlier you release them, the faster all users on older app versions are updated, and from that point on, the update process becomes reliable.
Key principle: Don’t stop development. Layer in infrastructure incrementally, proving value with each addition.
If your app is already live
- Triage gaps: Forced and suggested updates. + version monitoring in next release; feature flags + communication.
- Add to every new version: Implement forced update checks as soon as feasible. Users must first reach a version with the mechanism before it can be fully enforced, so backward compatibility may need to be maintained temporarily.
- Plan coordinated infrastructure release: Bundle everything, get leadership buy-in for 2-3 weeks
- Create migration path: Plan a migration path: after most users adopt forced updates, deprecate the old backend version while deciding how to handle remaining users based on organizational priorities.
Conclusion: speed vs. sustainability is a false choice
The most dangerous assumption we made was philosophical: that moving fast required cutting infrastructure. That speed and sustainability were opposing forces to be balanced.
Balancing speed and sustainability is challenging. Early on, rapid prototyping worked well, but eventually the process needed formal rules to ensure long-term stability.
At some point, proper infrastructure makes you faster. The chaos we created by moving fast without infrastructure eventually slowed us down more than implementing infrastructure ever would have. The NAF App is successful today because we delivered an MVP ready for production in just three months – a remarkable achievement given the scope and resources, and one that exceeded business expectations. Minor process improvements and implementing key takeaways would have added only 1–2 weeks, a small investment that would pay off over the coming months, providing a quick ROI for an app built to last
Key takeaway
If you’re building a mobile app with backend services, implement forced and suggested updates, manageable feature flags, communication to users and version monitoring from the very first production release. Everything else is negotiable. These three capabilities are the foundation that makes everything else possible.
Want to read our Case Study for EV Company? Click here!
Want to discuss with our Strategic Partnership Manager about increasing your business?
Contact Bart!