Skip to main content

The Universal Fidelity Port: Decoupling Modern Frontends from Frappe and Bespoke Backends

· 6 min read
Revant Nandgaonkar
Maintainer of Framework M

In enterprise engineering, teams often face a common dilemma: they want to build modern, high-density, cross-platform user interfaces, but their core data and business logic are anchored inside established ERP deployments, specialized telemetry services, or multi-language microservice clusters.

Historically, introducing a modern UI layer across diverse systems often triggered pressure to rewrite backends. At Framework M, we believe you should never have to rewrite a stable, functioning backend just to deliver a specialized frontend. We designed our architecture around a fundamental separation of concerns called the Dual Port Protocol.

Recently, we proved this model in a demanding real-world deployment—building a high-fidelity standalone frontend that simultaneously drives established Frappe backends, bespoke high-throughput microservices, and Framework M instances without any single backend owning or constraining the frontend.

Here is how the Universal Fidelity Port pattern works and how an authenticating gateway makes it seamless.


1. The Core Philosophy: Context Port vs. Fidelity Port​

Traditional web frameworks tightly couple UI generation with backend routing. The backend decides what HTML to render, what scripts to bundle, and how state is preserved.

In Framework M, we strictly divide the system into two independent ports:

  • The Context Port (Logical Hierarchy): Resolves who the user is, what organization/tenant they belong to, what records they are permitted to read, and what the entity tree looks like. It outputs clean, structured JSON manifests and APIs.
  • The Fidelity Port (Physical Rendering): Resolves how the application feels. It handles spatial layouts, animations, design tokens, component lifecycles, and device ergonomics (whether running on desktop web browsers, mobile apps, or embedded hardware).

Standalone UI Architecture

The realization is simple yet powerful: The Fidelity Port does not even need to be tied exclusively to a Framework M backend.

Because @framework-m/ui and @framework-m/desk are pure, headless React and Tamagui packages, they can run as an independent client consuming any backend that speaks HTTP.


2. The Gateway Glue: Reverse-Proxy Forward Auth​

When building a single frontend that unifies multiple disparate backends, the primary challenge is authentication fragmentation. You cannot expect a single browser tab to manage three different session cookies, four CSRF tokens, and conflicting refresh token cycles.

To solve this, we rely on Forward Authentication via Vouch Proxy (or Traefik ForwardAuth, Nginx auth_request, and OAuth2-Proxy).

  1. Centralized Identity: The user authenticates once at the gateway against an identity provider (OIDC, SAML, or corporate IdP).
  2. Domain Session Cookie: The gateway issues a unified domain session cookie (e.g., VouchCookie).
  3. Upstream Header Injection: When the browser makes requests to any downstream service under the gateway domain, the reverse proxy validates the session and injects verified identity claims:
    • X-Vouch-User: engineer@company.com
    • X-Vouch-IdP-Claims-Roles: Operator, Auditor

On the frontend, @framework-m/desk provides createForwardAuthProvider(), which delegates authentication entirely to the gateway. The frontend simply verifies the session via a lightweight /api/whoami endpoint, and the browser cookie jar handles the rest.


3. Four Real-World Backend Flavors​

By separating the Fidelity Port and unifying authentication at the gateway, the same frontend components can communicate with four distinct backend architectures:

Flavor 1: Standard Framework M Backend​

  • Browser Mode (Session Cookie): In web browsers, Framework M uses the Backend-For-Frontend (BFF) pattern with httpOnly, Secure session cookies. JavaScript cannot inspect or exfiltrate tokens, providing airtight protection against browser XSS attacks.
  • Device / Mobile Mode (Bearer Token): For native mobile apps (React Native / Expo), embedded tablets, or specialized hardware where browser cookie jars are absent, the same backend accepts Authorization: Bearer <jwt>. On dedicated hardware, storing tokens in hardware-backed secure enclaves (iOS Keychain or Android Keystore) maintains high security.

Flavor 2: Framework M Backend behind Vouch Proxy​

When Framework M sits behind the gateway, its HeaderAuthAdapter validates incoming proxy headers (X-Vouch-User). It automatically maps upstream roles to Framework M permissions without requiring in-app login forms.

Flavor 3: High-Throughput Bespoke Microservices​

Specialized microservices (such as high-speed ingestion engines written in Go or Python) do not need to implement complex user management or OAuth flows. They simply read the proxy headers and return JSON payloads directly to the frontend's Refine data providers.

Flavor 4: Established Frappe / ERPNext Deployments​

Many organizations run extensive Frappe and ERPNext installations that reliably handle core business operations, inventory, and accounting. However, they frequently need specialized mobile frontends, offline field tools, or embedded kiosk interfaces that benefit from modern cross-platform design systems.

For web browser access, the open-source castlecraft/vouch_frappe_auth hook allows Frappe to automatically authenticate requests using the reverse proxy's HTTP_X_VOUCH_USER header.

For native mobile apps (React Native / Expo), managing browser cookie hops can be cumbersome. Instead, teams can configure castlecraft/cfe on the Frappe backend. This allows Frappe to directly accept and validate standard Authorization: Bearer <jwt_token> access tokens issued by your upstream Identity Provider (Keycloak, Auth0, Okta).

On the frontend, developers simply import the built-in @framework-m/desk/frappe subsystem—which provides a pre-built Refine data provider (frappeDataProvider), dynamic DocType schema discovery (useFrappeDocType), and high-density view renderers (FrappeDocTypeView, FrappeListView).

Users enjoy a responsive, tactile React/Tamagui experience on their devices of choice, while the underlying Frappe backend continues running its proven business logic completely untouched.


4. Why This Architecture Matters​

This decoupled "Fidelity Port" approach transforms how software teams deliver value:

  1. Zero-Cliff Co-existence: You do not have to rewrite a million lines of backend business logic just to build a world-class mobile app or modern web dashboard.
  2. Unified User Experience: Operators interact with a single, cohesive design system across heterogeneous backends—an ERP entry, an IoT telemetry feed, and a bespoke reporting engine all look and feel like one unified product.
  3. True Frontend Sovereignty: Frontends can evolve, refactor, and migrate on their own release cycles, completely independent of backend database schemas or framework lifecycles.

Get Started​

Detailed step-by-step configuration recipes, code snippets for createForwardAuthProvider, and custom DataProvider implementations for each backend flavor are available in our official guide:

👉 Read the Full How-To Guide: Standalone UI with Multiple Backends