Mobile & Native Development
Framework M is designed as a 90% Mobile-Ready foundation. Because we utilize Tamagui for our design system and core layout components, your UI code is cross-platform by default.
This guide outlines how to bridge the remaining 10% of architectural logic to target React Native (iOS, Android) and Desktop (macOS, Windows).
Foundational 90% (Tamagui)
Our @framework-m/ui and @framework-m/desk libraries use Tamagui's Stacks and Themes. Tamagui's compiler automatically:
- Compiles to optimized atomic CSS for the Web.
- Compiles to standard React Native View/Text for mobile.
[!TIP] Always prefer Tamagui tokens (e.g.,
backgroundColor="$background") over raw CSS variables to ensure platform compatibility.
Getting Started with Native
Framework M libraries are published on NPM and PyPI. You can install them into any standard React Native or Expo project just like any other package.
pnpm add @framework-m/ui @framework-m/desk @framework-m/plugin-sdk
The Remaining 10%: Architectural Gaps
While 90% of your code (UI, business logic, and plugins) is cross-platform, you must address four specific architectural translations to bridge between Web and Native.
1. Unified Routing
The web-first shell uses react-router-dom. For Native, we recommend React Navigation for its high-performance flexibility in dynamic composition.
- Bridging Strategy: Use the
@framework-m/plugin-sdkto iterate over discovered plugins and dynamically generate a Stack or Tab navigator. - Expo Router Alternative: If you prefer file-based routing and web-parity, Expo Router is a high-quality alternative.
2. Unified Authentication & Tokens
Framework M utilizes a Unified Authentication Chain that allows a single backend to fulfillment of both Web and Native clients simultaneously. This the configured via the auth.strategies list in your framework_config.toml.
How Parallel Auth Works:
- Web (Session Strategy): The backend issues an
HttpOnlysession cookie—secure for browsers but difficult for native apps. - Native (JWT / OIDC Strategy): The backend accepts an
Authorization: Bearer <token>header.- In Indie Mode (
jwtstrategy): The backend issues its own internal JWT signed with a private Local JWT Secret. The Native app only holds the token; the secret must never be included in the app bundle. - In Federated Mode (
oidcstrategy): The backend directly accepts and validates an external OIDC token (e.g., Google, Azure AD, Auth0) using the configured[auth.oauth]providers, automatically fetching JWKS and caching public keys. - Behind an API Gateway (
gatewaystrategy): The backend trusts hydrated HTTP headers (e.g.,X-User-ID) injected by an upstream proxy that has already authenticated the native token.
- In Indie Mode (
[!CAUTION] Client Security: Your backend
JWT_SECRETor OIDCCLIENT_SECRETare private keys. Including them in a React Native or Desktop binary is a critical security failure. The client should only ever hold short-lived Tokens and long-lived Refresh Tokens in secure storage.
The Native Refresh Lifecycle:
- Client Ownership: The Native app is responsible for the refresh lifecycle. It must store the Refresh Token in secure storage (Keychain/Keystore).
- Graceful Refresh: Use a high-quality interceptor to catch
401 Unauthorizedresponses and negotiate a new Access Token before retrying the request.
3. Unified Storage
While the web shell uses localStorage, Native platforms require securely encrypted storage for tokens.
Implementation Recommendation:
// libs/framework-m-ui/src/storage.ts
import { Platform } from 'react-native';
// Standard native keychain wrapper
export const secureStorage = Platform.OS === 'web'
? null // Web should use HttpOnly Cookies, not local tokens
: require('react-native-keychain');
4. Unified API Bridge
Features like Camera, Biometrics, and Push Notifications require platform-specific permissions and APIs.
- Use Expo SDK for a high-quality set of universal APIs.
- Utilize the
Slotsystem in@framework-m/deskto provide Native-only entry points without affecting the web layout.