TL;DR: Moving Android from XML plus MVP to Compose plus MVI and consolidating iOS onto modern SwiftUI was really an architecture and testing reset, with navigation and concurrency debt shaping the hardest work, according to Passbolt. The lesson for identity teams is that legacy coexistence patterns always raise operational cost until the old model is fully removed.
At a glance
What this is: This is PassBolt’s account of modernising mobile UI architecture across Android and iOS, with the core finding that navigation, testing, and dual-stack coexistence created most of the migration pain.
Why it matters: It matters to identity practitioners because modernisation programmes fail in the same way when old and new control paths coexist, especially where state, navigation, and verification logic must be rebuilt together.
Context
Modern UI migration is the process of moving an application from older, imperative view stacks to a newer declarative architecture. In this article, PassBolt shows that the hardest work was not redrawing screens but realigning state flow, navigation, and test strategy across platforms.
The Android and iOS efforts both exposed the same structural issue: once two UI generations coexist, every bridge adds cost, uncertainty, and maintenance overhead. For identity teams, the pattern is familiar from lifecycle transitions where legacy and modern control paths remain active at the same time.
The practical lesson is not limited to mobile development. Any programme that keeps parallel models alive for too long creates hidden operational debt, and the longer that overlap lasts, the harder it becomes to retire the old system cleanly.
Key questions
Q: What breaks when old and new UI architectures have to coexist too long?
A: The migration starts accumulating hidden cost in navigation, testing, and state coordination. Each bridge between frameworks creates a new failure point, and the system becomes harder to reason about because different screens follow different rules. Coexistence can be managed temporarily, but it should never be treated as the end state.
Q: Why does navigation become the hardest part of a UI migration?
A: Navigation sits at the point where state, presentation, and module boundaries meet. If old and new stacks use different transition models, the application needs extra glue to move users cleanly between them, and that glue often becomes the most fragile part of the migration.
Q: How should teams plan test rewrites during a UI modernisation effort?
A: Plan the tests as part of the architecture change, not after it. When the state model and rendering system change, tests must move from legacy selectors and view lookups to assertions that match the new UI semantics and presentation boundaries.
Q: Should teams keep legacy UI patterns alive until the new stack is fully proven?
A: Only for a limited transition window. Leaving legacy patterns in place for too long multiplies maintenance work, hides architectural inconsistency, and delays the moment when the new model becomes the single source of truth for state and navigation.
Technical breakdown
Why declarative UI changes state flow and control boundaries
Declarative UI reverses the classic imperative model. Instead of pushing changes directly into the interface, the application describes state and lets the framework render the view from that state. PassBolt’s Android migration from XML plus MVP to Compose plus MVI shows why this matters: MVP’s bidirectional flow does not fit a unidirectional state model without reworking presentation boundaries. That shift changes how developers reason about state, user actions, and lifecycle behaviour. It also changes where bugs hide, because the UI becomes a reflection of state rather than a place where state is assembled informally. The architectural debt is not cosmetic; it sits in the interaction model itself.
Practical implication: teams should treat a UI paradigm shift as a state-architecture redesign, not a screen rewrite.
Why navigation becomes the hardest coexistence layer
Navigation is where separate architectural worlds collide. In PassBolt’s account, the most difficult parts were not isolated UI components but the bridge surfaces that had to connect old and new modules, especially during Android’s MVP to MVI transition and iOS’s multi-framework period. When navigation is split across patterns, each screen can behave differently depending on which stack owns it, which increases the chance of inconsistent state handoff, duplicated logic, and fragile transitions. This is why coexistence is expensive: every cross-stack path needs extra coordination, and the coordination itself becomes technical debt. Once navigation is the glue, the whole system inherits the weakest integration point.
Practical implication: map every bridge surface early and budget navigation refactors as a first-class workstream.
How test strategy changes when architecture is rebuilt
Testing changes because the selectors, state model, and presentation boundaries change. PassBolt describes moving from presenter-style tests and findViewById-heavy Espresso tests to Compose semantics, test tags, and ViewModel-oriented checks. That is not just a tooling migration; it is a change in what the tests are proving. With declarative UI, stable state assertions become more important than brittle element lookups, and tests become more sensitive to architecture quality. Swift 6 strict concurrency adds the same pattern on the iOS side: the compiler starts surfacing issues that older code tolerated. The result is that debt becomes visible at the exact moment the architecture becomes more enforceable.
Practical implication: plan the test rewrite alongside the architecture change, or the new stack will inherit old assumptions and flaky coverage.
NHI Mgmt Group analysis
Architectural coexistence is the real debt, not the UI framework itself. PassBolt’s migration shows that the expensive part of modernisation is the period when old and new models both remain live. That overlap multiplies state handling, test effort, and maintenance load across platforms. The practical conclusion is that coexistence windows must be treated as a formal governance risk, not a temporary inconvenience.
Navigation debt is the control plane of a UI migration. Screen rendering can be rewritten incrementally, but navigation and authentication determine whether separate architectures can safely coexist. When those bridge layers are fragmented, every transition becomes a special case and the migration loses its coherence. Practitioners should read this as a warning that the integration layer is where architectural programmes succeed or stall.
Test rewrites reveal whether the target architecture is actually simpler. If a modern stack still depends on brittle legacy selectors, manual regression, and duplicated verification patterns, the migration has only moved complexity rather than removed it. PassBolt’s experience shows that architectural debt becomes most visible when the verification model is forced to change. Teams should use that pressure as a signal, not a setback.
Strict concurrency turned hidden technical debt into enforceable risk. Swift 6 did not create the debt, but it made old assumptions about thread behaviour impossible to ignore. That is the same pattern identity programmes see when stricter policy or enforcement exposes weak lifecycle design. The lesson is that enforcement surfaces latent debt, and practitioners should expect that visibility rather than mistake it for instability.
Unification is the only durable end state. PassBolt’s Android and iOS journeys both point to the same principle: parallel patterns can be tolerated during migration, but they cannot be the destination. The longer a programme relies on transition glue, the more expensive every future change becomes. For platform teams, the governance objective is to eliminate duplicated operating models, not just modernise the surface.
What this signals
Migration debt compounds fastest at the bridge points. Teams usually focus on the visible rewrite, but the durable risk sits in the transitional layers that connect old and new systems. If those layers are not given explicit retirement plans, they become permanent sources of cost and confusion.
Verification must move with the architecture. A modern UI stack does not reduce risk if the test model still assumes the old presentation layer. The practical signal is simple: when a migration is real, the way you prove correctness changes with it.
For practitioners
- Define the target architecture before the first rewrite Establish the state model, navigation pattern, and test conventions on the first module so later work inherits one operating model rather than improvising per screen.
- Treat bridge layers as migration scope Inventory every place where old and new UI patterns must interoperate, then plan explicit retirement dates for those bridges instead of leaving them as permanent glue.
- Rewrite tests with the new architecture Replace legacy selector-heavy tests with checks that match the new rendering and state model, including state assertions, composable semantics, and concurrency-sensitive coverage.
- Remove duplicate presentation paths early Eliminate parallel UI patterns, view models, and controller logic as soon as a module stabilises, because long-lived coexistence increases maintenance and regression risk.
Key takeaways
- Modern UI migrations fail most often where state, navigation, and testing still depend on legacy patterns.
- PassBolt’s Android and iOS changes show that the real cost sits in coexistence, not in the visible screen rewrite.
- The durable fix is architectural unification, with bridge layers and old test assumptions removed as soon as the new model stabilises.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
CIS Controls v8, NIST CSF 2.0 and OWASP SAMM set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| CIS Controls v8 | CIS-16 — Application Software Security | The article is about changing application architecture and verification practices. |
| Recommendation — Review application change paths under CIS-16 and align testing with the new architecture before retiring legacy paths. | ||
| NIST CSF 2.0 | GV.PO-01 — Policy | The migration depends on clear architectural policy and sequencing across teams. |
| Recommendation — Define migration policy that sets the target architecture, bridge retirement, and ownership of testing changes. | ||
| OWASP SAMM | Implementation Governance — Implementation Governance | The article focuses on how architecture and test practices evolve during a software modernisation effort. |
| Recommendation — Use implementation governance to enforce a single migration playbook across modules and platforms. | ||
Key terms
- Declarative UI: A UI model where the screen is derived from current state rather than updated step by step through imperative commands. In large applications, this makes presentation more predictable because the source of truth is explicit and the UI reacts to state changes instead of being pushed into shape.
- Navigation bridge: A navigation bridge is the transitional logic that connects old and new UI stacks during a migration. It lets screens and modules interoperate temporarily, but it also becomes a concentration point for inconsistency, duplicated logic, and hard-to-remove technical debt.
- Strict concurrency: Strict concurrency is a compiler-enforced approach to thread safety that forces code to obey concurrency rules rather than relying on discipline alone. It surfaces latent race conditions and unsafe assumptions, which makes hidden debt visible when older code is brought into a stricter model.
- Technical debt: Legacy shortcuts or weak design choices that create future cost, risk, or operational friction. In identity programmes, technical debt often shows up as brittle trust relationships, inconsistent revocation, poor traceability, or controls that only work in one environment and fail in another.
Deepen your knowledge
NHI governance, agentic AI identity, and machine identity lifecycle are core topics in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are building or maturing an IAM programme, it is worth exploring.
Published by the NHIMG editorial team on July 8, 2026.
Updated on October 11, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org