# Architecture Decisions

This page explains the reasoning behind the Ledger Wallet architecture: why we adopted a feature-first structure, why we use the MVVM pattern, and how the codebase is evolving through migration.

---

## The Migration Journey

The Ledger Wallet codebase is undergoing a significant architectural evolution. Understanding the history helps make sense of the current state.

| Phase                          | Status              | Description                                                   |
| ------------------------------ | ------------------- | ------------------------------------------------------------- |
| **Legacy Code**                | Ongoing             | Pre-MVVM code in `apps/*/src/` — being progressively migrated |
| **MVVM Pattern**               | Standard (2+ years) | ViewModel pattern in `src/mvvm/` — used for new development   |
| **Feature-First Architecture** | In Progress         | New target: root-level `features/` folders                    |

The codebase currently contains three layers of code:

| Layer             | Location                        | Description                                                    |
| ----------------- | ------------------------------- | -------------------------------------------------------------- |
| **Legacy**        | `apps/*/src/` (outside `mvvm/`) | Pre-MVVM code, being progressively migrated                    |
| **MVVM**          | `apps/*/src/mvvm/`              | Code following the ViewModel pattern (2+ years of development) |
| **Feature-First** | Root `features/`                | New architecture target                                        |

This means:

- **New features** should be written in the [`features/`](https://github.com/LedgerHQ/ledger-live/tree/develop/features) folder at the monorepo root
- **MVVM code** in `src/mvvm/` follows the ViewModel pattern and will be progressively migrated to `features/`
- **Legacy code** predates MVVM and should be migrated when touched significantly
- **`libs/`** folder contains legacy shared libraries being progressively migrated into features

---

## Why Feature-First Architecture

The feature-first architecture is inspired by the C4 model and follows a deliberate philosophy:

- **Root level** contains everything connected to the exterior (apps, platform concerns)
- **One level deep** contains core business capabilities (features)
- **Two levels deep** contains feature-related business logic

### Design Goals

The architecture was designed to address specific pain points in the previous structure:

1. **Ease codebase discovery** — A clear, intuitive folder structure helps new contributors find what they need. Instead of navigating deep into platform-specific folders, features are visible at the root level.

2. **Highlight domain-specific code** — Domain-Driven Design principles make business logic explicit. Each feature encapsulates its own domain entities within its `data-layer/` subfolder.

3. **Balance folder depth** — The previous structure suffered from both deep nesting and flat file dumps. The new structure aims for a shallow, consistent depth across the codebase.

4. **Collocate synergizing files** — Related code (components, data-layer, tests) lives together within each feature, rather than being scattered across global folders.

5. **Unify mobile and desktop** — Instead of maintaining separate codebases for mobile and desktop, features use platform-specific file extensions (`.web.ts`, `.native.ts`) to keep code close together while respecting platform differences.

### Layer Responsibilities

| Layer           | Responsibility                                                                      |
| --------------- | ----------------------------------------------------------------------------------- |
| **`apps/`**     | Platform infrastructure — routing, state manager, observability. No business logic. |
| **`features/`** | Self-contained business features with high cohesion, low coupling                   |
| **`libs/`**     | Legacy shared libraries — being progressively migrated into features                |

The strict import boundaries between these layers enforce separation of concerns. Apps wire features together but should not contain business logic. This prevents circular dependencies and makes it possible to reason about each layer independently.

---

## Why MVVM

The MVVM (Model-View-ViewModel) pattern was adopted to address a specific problem: components that mix UI rendering with business logic (Redux selectors, API calls, state transformations) become difficult to test and maintain.

### Key Principles

1. **Separation of concerns** — UI components should be pure and receive data via props. All logic that connects to outer layers (store, network, etc.) lives in the ViewModel hook.

2. **Testability** — The View component can be tested in isolation with mock props, without needing to mock Redux, API calls, or any other external dependency. The ViewModel can be tested independently as a hook.

3. **Props injection** — The ViewModel hook result is spread as props to the View. This is a deliberate design choice: by injecting props rather than calling the hook inside the component body, you get a clear boundary between "what data to use" and "what to render."

### Benefits

| Benefit         | Description                                                      |
| --------------- | ---------------------------------------------------------------- |
| **Testability** | View components can be tested with simple prop mocking           |
| **Reusability** | Views can be reused with different ViewModels                    |
| **Clarity**     | Clear separation between "what to render" and "what data to use" |
| **Debugging**   | Easier to isolate issues to either UI or logic                   |

MVVM is not used everywhere — simple presentational components, pure utility components, and components that only receive props from parents don't need it. The pattern is reserved for components that connect to Redux, make API calls, or contain complex business logic.

---

## See also

- [Architecture reference](../reference/architecture) — Complete folder structure, import rules, platform extensions
- [MVVM Pattern reference](../reference/mvvm-pattern) — Implementation details and when to use
- [How to Structure a Feature](../how-to/structure-a-feature) — Step-by-step guide for applying this architecture
