UI Development & Web Preview
Build high-performance web frontends for 5M Phone with React 18, TypeScript, Tailwind CSS, and Vite.
Fast Local Development in Browser
The official template lets you build and test your app directly in your desktop browser without opening FiveM:
cd 5M_CustomApp/ui
npm install
npm run devVite will start a local development server at http://localhost:5173/. Open this link in Google Chrome.
Mock Bridge for Browser Testing
When running in browser outside of FiveM, phoneBridge.ts falls back to simulated data so your UI never crashes:
// ui/src/lib/phoneBridge.ts detects when window.GetParentResourceName is undefined
// and returns mock player data, mock coordinates, and simulated dark mode.Live In-Game HMR (Hot Module Replacement)
While developing inside FiveM, you can stream your live Vite development server directly into the in-game phone screen:
-
Start the Vite dev server on your machine:
Shellcd ui npm run dev -
In
5M_CustomApp/config.lua, set:LuaConfig.UiPath = 'http://localhost:5173/' -
Restart
5M_CustomAppin server console:restart 5M_CustomApp. -
Open 5M Phone in-game. Any CSS or TSX changes you save in VS Code will update instantaneously on the in-game phone screen without reloading!
Building for Production
When you are ready to deploy your app:
cd ui
npm run buildThis compiles your TypeScript and React source files into optimized, production-ready static assets in ui/dist/:
- Bundled and minified HTML, CSS, and JS.
- No external CDN dependencies or Node.js runtime required at FiveM runtime.
In config.lua, ensure Config.UiPath points back to the built bundle:
Config.UiPath = 'ui/dist/index.html'Automatic Dark & Light Theme Handling
5M Phone passes the player's active theme ('light' or 'dark') into your app iframe via query parameters:
import { applyTheme, getPhoneBridgeMeta } from './lib/phoneBridge';
export function App() {
const meta = getPhoneBridgeMeta();
useEffect(() => {
applyTheme(meta.theme);
}, [meta.theme]);
return (
<div className="min-h-full bg-white text-zinc-900 dark:bg-zinc-950 dark:text-zinc-100">
{/* App Content */}
</div>
);
}The applyTheme() helper sets data-theme="dark" or data-theme="light" on document.documentElement, allowing standard Tailwind dark: utility classes to activate automatically.
