Frontend Architecture
A consistent, layered architecture across Flutter, Angular, React, and React Native β enabling you to build on top of shared Foundation infrastructure without rebuilding common capabilities.
Layered Composition
Every frontend platform follows the same three-layer model:
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Product Applications β
β Domain-specific screens, business logic, UX β
βββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Product SDKs (optional) β
β Domain packages that extend the Foundation β
βββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Foundation Layer β
β Auth, theming, error handling, UI components, β
β REST clients, data layer, CI/CD β
βββββββββββββββββββββββββββββββββββββββββββββββββββEach layer depends only downward. Foundation packages never reference product code. Product SDKs extend Foundation capabilities for a specific domain. Product apps compose both layers into a deployable experience.
| Platform | Foundation Repo | Packages |
|---|---|---|
| Flutter | sdks-flutter (Melos) | 26 |
| Angular | sdks-angular (Nx) | 26 |
| React / RN | sdks-react (pnpm + Turborepo) | ~24 |
Dependency Injection
Each platform provides an abstraction layer over its DI mechanism, keeping SDK code framework-agnostic:
| Platform | Abstraction | Implementation | Consumption |
|---|---|---|---|
| Flutter | Abstract DependencyInjector interface in e11_core | GetDependencyInjector (GetX) in e11_infra | di.find<T>(), di.put(), di.lazyPut() |
| Angular | BaseConfigProvider + forRoot() on every SDK module | Angularβs built-in DI with InjectionToken | { provide: BaseXxxConfigProvider, useClass: ConcreteProvider } |
| React / RN | Awilix-style DI container with hooks | useRegisterProviders + useContainer | useContainer() in any component |
The Flutter DI abstraction is the most decoupled β the GetX dependency is an implementation detail that product code never touches. Angular uses its native DI but standardizes the pattern. React/RN uses a lightweight container with React hooks.
SDK Composition
Product apps wire Foundation SDKs together at startup. Each platform has a consistent βone call per SDKβ initialization pattern:
Flutter β static initialize() factories that self-register dependencies:
AuthSdk.initialize(config: AuthConfig(di: di, ...));
MessagingSdk.initialize(config: MessagingConfig(di: di, ...));
FilesSdk.initialize(config: FilesConfig(di: di, ...));Angular β forRoot() module imports with config providers:
AuthModule.forRoot({ configProvider: AuthConfigProvider }),
FilesModule.forRoot({ configProvider: FilesConfigProvider }),
MessagingModule.forRoot({ configProvider: MessagingConfigProvider }),React / RN β nested provider composition:
<FirebaseProvider {...config}>
<AuthSdkProvider>
<FilesProvider uploadConfig={config}>
<MessagingProvider>
{children}
</MessagingProvider>
</FilesProvider>
</AuthSdkProvider>
</FirebaseProvider>Feature Organization
All platforms organize code by domain feature, not by file type:
feature/
βββ data/ # Services, repositories, state
βββ ui/ # Screens, components, controllers
βββ resources/ # Constants, permissions, config| Concept | Flutter | Angular | React / RN |
|---|---|---|---|
| Feature entry point | Module facade (mixin with dependencies() + show()) | NgModule with routing module | Provider + exported hooks |
| State management | SafeValueNotifier + stores | @ngrx/component-store | TanStack Query + context |
| Routing | Abstract NavigationService with context.push() | Lazy-loaded NgModule routes with guards | Next.js App Router (web), Expo Router (mobile) |
| Backend integration | Dio-based RestClient with interceptors | HttpClient with interceptors | Axios-based RestClient with interceptors |
| Data layer | Firestore wrappers + typed REST clients | Firestore services + REST services | IRepository abstraction + TanStack Query hooks |
Backend Integration
Every platform provides typed clients for the Foundation backend with automatic auth token injection:
- REST β HTTP clients wrap Dio (Flutter), Angular
HttpClient, or Axios (React/RN) with interceptors that attach JWT bearer tokens, Firebase AppCheck tokens, and tenant ID headers on every request - Firestore β Real-time stream wrappers provide
streamDocument,streamCollection, query builders, and pagination with graceful permission-denied handling - Search β Algolia integration with platform-native search UI (InstantSearch for Angular/React, direct client for Flutter)
- Push Notifications β Firebase Cloud Messaging with platform-specific token management and routing
Shared Foundation Capabilities
These capabilities are provided across all platforms:
| Capability | Flutter | Angular | React (Web) | React Native |
|---|---|---|---|---|
| Authentication (Firebase Auth) | β | β | β | β |
| White-label tenant theming | β | β | β | β |
| Structured error handling | β | β | β | β |
| Error monitoring (Rollbar) | β | β | β | β |
| REST client with auth | β | β | β | β |
| Firestore data layer | β | β | β | β |
| UI component library | 140+ | ~65 | ~45 | ~35+ |
| File management | β | β | β | β |
| Push notifications | β | β | β | β |
| Messaging | β | β | β | β |
| Search (Algolia) | β | β | β | β |
| CI/CD pipelines | β | β | β | β |
| RBAC / Permissions | β | β | β | β |
Next Steps
- Platforms β Deep-dive into each platformβs capabilities
- Capabilities β Authentication, theming, error handling, state, testing, performance, build/deploy, component libraries, and SDKs