Consolidating seven apps into one platform
How 100+ banks went from juggling seven logins to a single microfrontend platform that loads three times faster.
7 → 1
applications consolidated
Role
Architecture proposal, frontend lead
Timeframe
2024 – 2026
Stack
React · Module Federation · Monorepo · Clerk · TypeScript
The problem
Interface.ai's conversational AI platform had grown one product at a time, and it showed. By 2024, more than a hundred banks and credit unions were operating across seven separate applications — seven login flows, seven navigation patterns, seven slightly different design languages. Each app bundled its own React instance and its own copy of every vendor library.
The user-facing symptom was brutal: 5–6 second page loads and constant context-switching for bank operations teams. The engineering symptom was worse: every cross-cutting change (auth, theming, telemetry) had to be implemented seven times, and drift between the apps compounded with every release.
The constraints
- All seven apps had to keep working for live banking customers throughout the migration — no downtime, no big-bang cutover.
- Teams owned their apps independently; the architecture had to preserve autonomous deploys rather than force a single release train.
- Banking customers meant strict auth and RBAC requirements — permissions could not regress for a single tenant.
- The business would not pause feature work for a rewrite. The consolidation had to happen alongside normal delivery.
Admin Console
own React
own auth
own deploy
Analytics
own React
own auth
own deploy
Bot Builder
own React
own auth
own deploy
Knowledge Base
own React
own auth
own deploy
Agent Desktop
own React
own auth
own deploy
Reporting
own React
own auth
own deploy
Settings
own React
own auth
own deploy
7 logins
5–6s loads
every change ×7
Decisions & trade-offs
Monorepo + microfrontends over a single merged app
I proposed a monorepo with Module Federation microfrontends: one shell owning auth, navigation, and design tokens, with each legacy app migrating in as a federated remote. Teams kept independent deployability; users got one coherent product.
Trade-off: Module Federation added real build complexity and version-coupling discipline — upgrading React affects every remote. A single merged SPA would have been simpler but would have serialized seven teams into one deploy queue.
Centralized auth with Clerk + RBAC in the shell
Authentication and role-based access moved into the shell as a platform capability. Remotes consume the session rather than implementing login. One security review surface instead of seven.
Trade-off: Every app had to migrate off its own auth flow, which meant carefully mapping seven permission models onto one RBAC scheme before any UI work could land.
Incremental tenant migration, dual-running systems
Tenants moved to the unified platform in waves while old apps stayed live. A shared vendor chunk, per-route code splitting, and parallelized API calls landed as part of the same effort.
Trade-off: Dual-running meant maintaining two deployment pipelines for months. The upfront cost was real — the hardest part of the project wasn't the design, it was convincing stakeholders the payoff justified it.
The outcome
Seven legacy applications became one Unification platform. Page load dropped from 5–6 seconds to 1–2 seconds, and the Lighthouse performance score climbed from roughly 45 to 85+.
Cross-cutting changes now land once instead of seven times. New micro-apps join the platform through an established pattern rather than a fresh negotiation — the architecture scaled cleanly as products were added.
Apps to maintain
Page load
Lighthouse score
What I'd do differently
I'd invest in contract tests between the shell and remotes from day one. We caught integration drift in staging more often than I'd like; explicit contracts would have caught it in CI.
I'd also push for a shared design-token package before the first remote migrated instead of midway through — retrofitting tokens across three already-migrated apps was avoidable churn.