Jan 22, 2026

7 mins

Architecture, Developer Productivity

Build Apps That Ship: Simple Architecture Rules for iOS and Mobile Teams (Part 1)

For the past decade I’ve seen the same story repeat itself: developers overbuild and overthink their architecture like they’re preparing for an alien invasion. They prepare the codebase for “millions of users” and because they never achieve product-market fit, that day never comes.


The funny part? Ninety percent of those “future scaling” fears are not real - but the over-engineered architecture becomes a very real problem on day one.


Here’s the cold truth:

  • Most products serve a few thousand loyal users and it’s those users who create the most revenue.

  • Most apps we build are not the next Instagram or TikTok.

  • Most dev companies and teams build multiple apps in parallel and don’t have time for the founder’s anxiety.

  • Most “critical” decisions made early in a project are based on guesses, not data - because there is no data yet.


A complicated architecture doesn’t just slow development - it kills motivation, burns people out, and makes every task heavier than it should be.


But here’s the twist:


Complicated architecture is bad…


but having no architecture at all is just as dangerous.


When there’s no structure, the codebase becomes a jungle built by five different people on five different days, each in a different mood. Nothing is predictable, everything is hard to reuse, and every feature feels like hacking something together instead of building a real product. So the real enemy isn’t “too much” or “too little.”


It’s the lack of a simple, consistent structure that everyone understands.


That’s why simplicity always wins.


So how do you build products that work, ship on schedule, and stay simple? Here’s what I’ve learned over the past few years as a developer on some of the biggest and simplest projects in your app store.

Why Developers Struggle


First, many founders create a theoretical architecture designed for some future case. This architecture assumes that everything is green lights, that millions of people are waiting for the product, and that the coders will have no trouble building something that is more philosophical than practical.


There’s one problem. When a founder requests “aspirational” code, the entire system breaks down. This is because the people that the founder hires eventually lose the plot and the complex dream software can’t be built.


Why?


Because the teams building the software can never be inside the founders head and, what’s worse, the original coders almost always disappear, creating a game of telephone in which the original vision is diluted or mutated. In real teams, this happens constantly:

  • people leave

  • teams shift

  • companies change vendors


It’s normal.


What’s not normal is expecting new developers to survive a codebase that even the original author struggled with.


Every time a company switches dev teams or hires new engineers, they waste weeks or months just trying to understand “what the previous devs were doing.”

We’ve seen many projects where devs from another company tried to build some fancy, trendy architecture, got lost inside their own maze, and eventually got replaced. Then we had to jump in, clean up, and rescue the project.


In fact, here’s the truth every developer knows:


Difficult features don’t scare engineers.


Messy architecture does.


And the first step to fixing the mess is brutally simple:


Make it simpler. If it feels too complicated, something is already wrong.

Kill the Monster


Every team has that one cursed part of the codebase nobody wants to touch.


Everyone says things like:

“I don’t know what’s going on here.”
“The previous team messed this up.”
”Don’t rewrite it. Copy the monster pattern. We’re not ready for a full refactor.”


And with today’s AI tools - Claude, ChatGPT, Gemini whatever - you can’t pretend the monster can’t be understood anymore. The robots will literally explain your own code to you, sometimes better than the person who wrote it. If you’re careful, you can even use these tools to refactor your code to make everything clearer.


One time, however, we found a hairball so wooly in a code base that even Claude was stumped. Why the code did what it did and how it did what it did was a mystery. It was some kind of strange cancer, stuck directly inside the base.


“Congrats,” the head dev told me. You’ve discovered legacy code so ancient it defeats modern technology.”


The dev eventually stopped laughing and told me something that stuck with me forever: Killing the monster is easier than living with it forever. No matter how much the founder loves the code, no matter how many times it’s been edited and modified, you have to kill your darlings.


Once it’s killed, the whole team moves faster and breathes easier.

Building to Survive the Chaos


Developers and architects forget this all the time: products change constantly. Chaos often reigns. But it doesn’t have to.


First, you have to get the idea of a “finished product” out of your head. The idea of a “finished product” died a long time ago. Things just keep changing forever, usually right after you finish building the previous version.

  • features evolve

  • UI gets redesigned

  • logic is updated

  • new concepts appear

  • old features get removed

  • users request new functionality

  • business needs shift weekly


This is normal.


So building your architecture tightly around the features you currently have is a huge mistake. Because next month those features will change - and your whole architecture collapses with them.


That’s why architecture shouldn’t be feature-driven - features come and go like interns in a startup.


Architecture should be module-driven.


You want modules you can:

  • plug in

  • unplug

  • update independently

  • replace without touching the rest

  • rewrite without breaking everything


That’s how your apps survive real-world chaos.

The Real Solution: Modularity 


As a mobile team lead working across multiple apps, I want one thing:

A universal, predictable structure that any developer can jump into without spending two weeks trying to “understand the architecture.”


If every project feels like a different planet, you won’t just burn out - you’ll need a NASA onboarding program just to understand how navigation works.


Different folder structures, naming conventions, navigation patterns, or state management approaches across apps create chaos.


Consistency is not boring. Consistency is what makes teams scalable.


Consistency:

  • creates speed.

  • reduces onboarding time.

  • helps junior devs grow.

  • lets senior devs focus on building instead of re-learning.


And most importantly - it keeps everyone sane.


A universal architecture doesn’t mean copy-pasting code everywhere.


It means having the same:

  • flow

  • logic organization

  • module boundaries

  • way of thinking


…so every app feels familiar from day one.

The Most Important Rule In Architecture


There are no universal rules you must follow.


No architecture is objectively correct.


You don’t need to copy how Google structures Android internally or how Apple organizes their frameworks.


And you definitely don’t need to follow whatever the internet says is “the right way.”


What you need to do is build a structure that works for your people, your deadlines, and your product.


If that means simplifying what others overcomplicate - do it.


If that means reusing the same structure across 20 apps - great.


If that means ignoring trendy architectures - even better.


Because at the end of the day, the goal is simple:

  • Ship real products.

  • Ship them reliably.

  • Ship them without destroying your team.


Ideally before the business team changes the requirements again - usually while you’re still deploying the previous version.

One last note: this article looks at architecture in a single-stack setup, like an iOS/Swift project. If you’re building iOS, Android, and Web at the same time, that is a different problem with its own specific headaches. When I get some free time, I’ll write the next part with concrete examples and some of that chaos we can break down.